package com.qianhe.controller;

import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletResponse;

import com.qianhe.common.config.RuoYiConfig;
import com.qianhe.common.constant.Constants;
import com.qianhe.common.core.domain.entity.SysUser;
import com.qianhe.common.exception.BusinessException;
import com.qianhe.common.utils.SecurityUtils;
import com.qianhe.common.utils.StringUtils;
import com.qianhe.common.utils.ip.IpUtils;
import com.qianhe.domain.GgFjb;
import com.qianhe.domain.SjZdsc;
import com.qianhe.service.IGgFjbService;
import com.qianhe.util.LogUtil;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.qianhe.common.annotation.Log;
import com.qianhe.common.core.controller.BaseController;
import com.qianhe.common.core.domain.AjaxResult;
import com.qianhe.common.enums.BusinessType;
import com.qianhe.service.ISjZdscService;
import com.qianhe.common.utils.poi.ExcelUtil;
import com.qianhe.common.core.page.TableDataInfo;

/**
 * 基层三册Controller
 *
 * @author qianhe
 * @date 2025-08-04
 */
@RestController
@RequestMapping("/system/sjZdsc")
public class SjZdscController extends BaseController
{
    @Autowired
    private ISjZdscService sjZdscService;
    @Autowired
    private IGgFjbService fjbService;

    /**
     * 查询基层三册列表
     */
    @GetMapping("/list")
    public TableDataInfo list(SjZdsc sjZdsc)
    {

        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件管理", "查询上传三基制度标准、基层单位三册", "查询");

        startPage();
        List<SjZdsc> list = sjZdscService.selectSjZdscList(sjZdsc);
        return getDataTable(list);
    }

    /**
     * 导出基层三册列表
     */
    @Log(title = "基层三册", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SjZdsc sjZdsc)
    {
        List<SjZdsc> list = sjZdscService.selectSjZdscList(sjZdsc);
        ExcelUtil<SjZdsc> util = new ExcelUtil<SjZdsc>(SjZdsc.class);
        util.exportExcel(response, list, "基层三册数据");
    }

    /**
     * 获取基层三册详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {

        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件管理", "查询上传三基制度标准、基层单位三册", "查询");

        return success(sjZdscService.selectSjZdscById(id));
    }

    /**
     * 新增基层三册
     */
    @Log(title = "基层三册", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody SjZdsc sjZdsc)
    {

        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件管理", "新增上传三基制度标准、基层单位三册", "新增");

        int i = sjZdscService.insertSjZdsc(sjZdsc);

        String fileListStr1 = sjZdsc.getFileListStr1();
        int i1 = fjbService.batchSaveFj(sjZdsc.getId()+"", "基层三册", "基层三册", fileListStr1);

        return toAjax(i);
    }

    /**
     * 修改基层三册
     */
    @Log(title = "基层三册", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody SjZdsc sjZdsc)
    {

        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件管理", "修改上传三基制度标准、基层单位三册", "修改");

        String fileListStr1 = sjZdsc.getFileListStr1();
        int i1 = fjbService.batchSaveFj(sjZdsc.getId()+"", "基层三册", "基层三册", fileListStr1);

        return toAjax(sjZdscService.updateSjZdsc(sjZdsc));
    }

    /**
     * 删除基层三册
     */
    @Log(title = "基层三册", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {

        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件管理", "删除上传三基制度标准、基层单位三册", "删除");

        return toAjax(sjZdscService.deleteSjZdscByIds(ids));
    }


    /**
     * 批量导出
     * 导出zip
     */
//    @RequestMapping(value = "/exportZip", method = {RequestMethod.GET, RequestMethod.POST})
//    public void exportZip(HttpServletResponse response, @RequestBody SjZdsc sjZdsc)  throws IOException
//    {
//        Long id = Long.parseLong(sjZdsc.getIds());
//        SjZdsc en = sjZdscService.selectSjZdscById(id);
//        String zdmc = en.getZdmc();
//        String bb = en.getBb();
//        List<GgFjb> fjs = en.getFileList1();
//
//        String ip = IpUtils.getIpAddr();
//
//        // 设置响应头
//        response.setContentType("application/zip");
////        response.setContentType("application/octet-stream");
//        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(zdmc + " " + bb + ".zip", "UTF-8"));
//        response.setCharacterEncoding("UTF-8");
//
////        Workbook exl = null;
////        OutputStream out = null;
////        InputStream in  = null;
//
//        // 创建ZIP输出流
//        try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
//
//            // 临时变量用于验证是否有有效文件被添加
//            boolean hasValidFile = false;
//
//            for(GgFjb fj:fjs) {
//                String fjlj = fj.getFJDZ();//附件路径
//                String fjmc = fj.getFJMC();//附件名称
//
//                String localPath = RuoYiConfig.getProfile();
//                String downloadPath = localPath + StringUtils.substringAfter(fjlj, Constants.RESOURCE_PREFIX);
//
//                // 1. 验证文件存在性和可读性
//                File file = new File(downloadPath);
//                // 验证文件
//                if (!file.exists() || !file.isFile() || !file.canRead() || file.length() == 0) {
//                    System.out.println("跳过无效文件: " + downloadPath);
//                    continue;
//                }
//
//                try (FileInputStream fis = new FileInputStream(file)) {
//                    // 3. 处理文件名（避免特殊字符）
//                    String safeFileName = fjmc.replaceAll("[\\\\/:*?\"<>|]", "_");
//                    ZipEntry entry = new ZipEntry(safeFileName);
//                    zos.putNextEntry(entry);
//
//                    // 使用缓冲区流式传输文件内容
//                    byte[] buffer = new byte[4096];
//                    int bytesRead;
//                    while ((bytesRead = fis.read(buffer)) != -1) {
//                        zos.write(buffer, 0, bytesRead);
//                    }
//                    zos.closeEntry();
//                    hasValidFile = true;
//                } catch (Exception e) {
//                    System.out.println("处理文件失败: " + downloadPath + " - " + e.getMessage());
//                    // 确保关闭当前条目
//                    try {
//                        zos.closeEntry();
//                    } catch (IOException ex) {
//                        // 忽略关闭异常
//                    }
//                }
//            }
//
//
//            if (!hasValidFile) {
//                throw new BusinessException("没有可导出的有效文件");
//            }
//        } catch (BusinessException e) {
//            throw e;
//        } catch (Exception e) {
//            throw new BusinessException("导出文件失败: " + e.getMessage());
//        }
//    }
    @RequestMapping(value = "/exportZip", method = {RequestMethod.GET, RequestMethod.POST})
    public void exportZip(HttpServletResponse response, @RequestBody SjZdsc sjZdsc) throws IOException {

        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件管理", "导出上传三基制度标准、基层单位三册", "导出");

        Long id = Long.parseLong(sjZdsc.getIds());
        SjZdsc en = sjZdscService.selectSjZdscById(id);
        String zdmc = en.getZdmc();
        String bb = en.getBb();
        List<GgFjb> fjs = en.getFileList1();


        // 设置响应头
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(zdmc + " " + bb + ".zip", "UTF-8"));

        Workbook exl = null;
        OutputStream out = null;
        InputStream in  = null;

        // 创建ZIP输出流
        try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
            for(GgFjb fj:fjs) {
                String fjlj = fj.getFJDZ();//附件路径
                String fjmc = fj.getFJMC();//附件名称

                String localPath = RuoYiConfig.getProfile();
                String downloadPath = localPath + StringUtils.substringAfter(fjlj, Constants.RESOURCE_PREFIX);


                // 将Excel转换为PDF
                byte[] pdfBytes = getFileBytes(downloadPath);

                String safeFileName = fjmc.replaceAll("[\\\\/:*?\"<>|]", "_");
                // 创建ZIP条目
                ZipEntry entry = new ZipEntry(safeFileName);
                zos.putNextEntry(entry);
                // 写入PDF文件到ZIP条目
                zos.write(pdfBytes);
                zos.closeEntry();
            }
        }catch (Exception e){
            e.getMessage();
            throw new BusinessException("导出Excel失败，请联系网站管理员！");
        }finally {
            if (exl != null) {
                try {
                    exl.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据文件路径获取字节数组
     * @param filePath 文件绝对路径
     * @return 文件内容的字节数组，若文件不存在或读取失败则返回null
     */
    public static byte[] getFileBytes(String filePath) {
        File file = new File(filePath);

        // 验证文件是否存在且为正常文件
        if (!file.exists() || !file.isFile()) {
            System.out.println("文件不存在或不是有效文件: " + filePath);
            return null;
        }

        // 验证文件大小（避免过大文件导致内存溢出）
        if (file.length() > Integer.MAX_VALUE) {
            System.out.println("文件过大，不适合转为byte[]: " + filePath);
            return null;
        }

        try (FileInputStream fis = new FileInputStream(file);
             BufferedInputStream bis = new BufferedInputStream(fis);
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {

            byte[] buffer = new byte[8192]; // 8KB缓冲区
            int bytesRead;

            // 循环读取文件内容到字节数组输出流
            while ((bytesRead = bis.read(buffer)) != -1) {
                baos.write(buffer, 0, bytesRead);
            }

            // 强制刷新缓冲区，确保所有数据都被写入
            baos.flush();

            return baos.toByteArray();

        } catch (FileNotFoundException e) {
            System.out.println("文件未找到: " + filePath + "，错误: " + e.getMessage());
        } catch (IOException e) {
            System.out.println("读取文件失败: " + filePath + "，错误: " + e.getMessage());
        }

        return null;
    }


    /**
     * 批量提交
     */
    @PostMapping(value = "/pltj")
    public AjaxResult pltj(@RequestBody SjZdsc sjZdsc)
    {
        sjZdsc.setZt("1");
        return success(sjZdscService.pltj(sjZdsc));
    }



    /**
     * 查询 共享出来的 根据 gxqx这个字段 分别取
     */
    @GetMapping("/gxList")
    public TableDataInfo gxList(SjZdsc sjZdsc)
    {
        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件共享", "查询共享的文件", "查询");

        startPage();
        sjZdsc.setNowUserName(SecurityUtils.getUsername());
        sjZdsc.setNowUserDeptId(String.valueOf(SecurityUtils.getDeptId()));
        List<SjZdsc> list = sjZdscService.gxList(sjZdsc);
        return getDataTable(list);
    }
    /**
     * 查询 门户上的 公开的
     */
    @GetMapping("/gxgkList")
    public TableDataInfo gxgkList(SjZdsc sjZdsc)
    {
        //日志
        SysUser u = SecurityUtils.getLoginUser().getUser();
        LogUtil.mkrzsc(u, "文件手册", "文件手册-文件共享", "查询共享的文件", "查询");

        startPage();
        sjZdsc.setNowUserName(SecurityUtils.getUsername());
        sjZdsc.setNowUserDeptId(String.valueOf(SecurityUtils.getDeptId()));
        List<SjZdsc> list = sjZdscService.gxgkList(sjZdsc);
        return getDataTable(list);
    }
}
