package com.ruoyi.gysl.service.impl;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.utils.PdfMerger;
import com.itextpdf.layout.font.FontProvider;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.gysl.entity.GyslProjectHandbook;
import com.ruoyi.gysl.entity.request.HandbookRequest;
import com.ruoyi.gysl.entity.response.BasicInformationResponse;
import com.ruoyi.gysl.mapper.BasicInformationMapper;
import com.ruoyi.gysl.mapper.ProjectHandBookMapper;
import com.ruoyi.gysl.service.BasicInformationService;
import com.ruoyi.gysl.service.GyslProjectHandbookService;
import com.ruoyi.system.mapper.SysDictDataMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.*;

/**
 * 项目手册(GyslProjectHandbook)表服务实现类
 *
 * @author makejava
 * @since 2025-04-14 13:56:59
 */
@Slf4j
@Service("gyslProjectHandbookService")
public class GyslProjectHandbookServiceImpl extends ServiceImpl<ProjectHandBookMapper, GyslProjectHandbook> implements GyslProjectHandbookService {


    @Resource
    private BasicInformationMapper basicInformationMapper;

    @Resource
    private BasicInformationService basicInformationService;
    @Resource
    private SysDictDataMapper sysDictDataMapper;

    /**
     * 分页查询所有数据
     *
     * @param g 查询实体
     * @return 所有数据
     */
    @Override
    public Page<GyslProjectHandbook> page(Page<GyslProjectHandbook> a1, HandbookRequest g) {
        return baseMapper.page(a1, g);
    }

    @Override
    public void generatePdfs(HttpServletResponse response, Integer id) throws IOException {
        // 获取数据
        GyslProjectHandbook handbook = getById(id);
        List<BasicInformationResponse> basicInfoList = basicInformationMapper.idListToProject(
                Arrays.asList(handbook.getXmId().split(",")));
        List<String> hbpdf = new ArrayList<>();
        // 配置中文字体
        String fontPath = RuoYiConfig.getProfile() + "/Alibaba-PuHuiTi-Regular.ttf";
        FontProvider fontProvider = new FontProvider();
        fontProvider.addFont(fontPath, PdfEncodings.IDENTITY_H);
        // 转换参数
        ConverterProperties props = new ConverterProperties();
        props.setFontProvider(fontProvider);
        //封面
        String htmlHead = RuoYiConfig.getProfile() + "/head.txt";
        String s = getHtml(htmlHead);
        s = s.replace("{{scname}}", handbook.getName() != null ? handbook.getName() : "/");
        s = s.replace("{{subtitleone}}", handbook.getSubtitle1() != null ? handbook.getSubtitle1() : "/");
        s = s.replace("{{subtitletwo}}", handbook.getSubtitle2() != null ? handbook.getSubtitle2() : "/");
        s = s.replace("{{fmimgurl}}", Paths.get(RuoYiConfig.getProfile() + "/1.png").toUri().toString());
        String headPdf = RuoYiConfig.getProfile() + "/pdfml" + "/head" + ".pdf";
        hbpdf.add(headPdf);
        FileUtil.touch(headPdf);
        try (PdfWriter writer = new PdfWriter(headPdf);
             PdfDocument pdf = new PdfDocument(writer)) {
            HtmlConverter.convertToPdf(s, pdf, props);
        }
        //内容目录
        String htmlUrl = RuoYiConfig.getProfile() + "/gysl.txt";
        String original = getHtml(htmlUrl);
        for (int i = 0; i < basicInfoList.size(); i++) {
            //查看每个项目对应的附件
            StringBuilder result = new StringBuilder(original);
            if (basicInfoList.get(i).getBasicInformation().getFj() != null) {
                String[] split = basicInfoList.get(i).getBasicInformation().getFj().split(",");
                String target = "<!-- 图片区域 -->";    // 要查找的子字符串
                int startIndex = original.indexOf(target);
                if (startIndex == -1) {
                    throw new IllegalArgumentException("未找到目标子字符串");
                }
                int insertPosition = startIndex + target.length();
                result = new StringBuilder(original.substring(0, insertPosition));
                for (int i1 = 0; i1 < split.length; i1++) {
                    String changeStr = "<div class=\"image-container\">\n" +
                            "\t\t<img src=\"{{fjimg"+i1+"}}\" alt=\"\" class=\"content-img\">\n" +
                            "\t</div>"; // 要插入的内容
                    result.append(changeStr);
                }
                result.append(original.substring(insertPosition));
            }
            //获取当前的信息并替换为可用html
            String htmlNew = changeData(String.valueOf(result), basicInfoList.get(i));
            //新建pdf
            String newPdf = "/pdfml" + "/p" + i + ".pdf";
            String outputPath = RuoYiConfig.getProfile() + newPdf;
            hbpdf.add(outputPath);
            FileUtil.touch(outputPath);
            try (PdfWriter writer = new PdfWriter(outputPath);
                 PdfDocument pdf = new PdfDocument(writer)) {
                HtmlConverter.convertToPdf(htmlNew, pdf, props);
            }
        }
        //封尾
        String htmlFoot = RuoYiConfig.getProfile() + "/foot.txt";
        String a = getHtml(htmlFoot);
        a = a.replace("{{dwname}}", handbook.getDwname() != null ? handbook.getDwname() : "/");
        a = a.replace("{{name}}", handbook.getLxname() != null ? handbook.getLxname() : "/");
        a = a.replace("{{phone}}", handbook.getPhone() != null ? handbook.getPhone() : "/");
        a = a.replace("{{date}}", handbook.getDate() != null ? handbook.getDate() : "/");
        a = a.replace("{{Address}}", handbook.getAddress() != null ? handbook.getAddress() : "/");
        a = a.replace("{{fmimgurl}}",
                Paths.get(RuoYiConfig.getProfile() + "/2.png").toUri().toString());
        String foodPdf = RuoYiConfig.getProfile() + "/pdfml" + "/food" + ".pdf";
        hbpdf.add(foodPdf);
        FileUtil.touch(foodPdf);
        try (PdfWriter writer = new PdfWriter(foodPdf); PdfDocument pdf = new PdfDocument(writer)) {
            HtmlConverter.convertToPdf(a, pdf, props);
        }
        // 创建内存输出流（替代写入ceshi.pdf文件）
        ByteArrayOutputStream mergedPdfStream = new ByteArrayOutputStream();
        // 初始化PdfWriter指向内存流
        PdfWriter writer = new PdfWriter(mergedPdfStream);
        PdfDocument mergedPdfDoc = new PdfDocument(writer);
        PdfMerger merger = new PdfMerger(mergedPdfDoc);
        // 合并所有PDF
        for (String src : hbpdf) {
            try (PdfDocument srcDoc = new PdfDocument(new PdfReader(src))) {
                merger.merge(srcDoc, 1, srcDoc.getNumberOfPages());
            }
        }
        merger.close();
        mergedPdfDoc.close(); // 关闭合并的PDF文档
        //删除临时生成的pdfml文件夹及其内容
        String pdfmlDirPath = RuoYiConfig.getProfile() + "/pdfml";
        try {
            FileUtil.del(pdfmlDirPath); // Hutool工具类删除文件夹（含内部文件）
        } catch (Exception e) {
            log.error("删除临时文件夹失败: {}");
            // 可根据需要决定是否抛出异常或仅记录日志
        }

        // 设置响应头
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=\"product_catalog.pdf\"");
        response.setContentLength(mergedPdfStream.size());
        // 将内存流写入HTTP响应
        try (OutputStream out = response.getOutputStream()) {
            mergedPdfStream.writeTo(out);
            out.flush();
        }
    }

    /**
     * 获取html对应得string
     */
    public static String getHtml(String htmlUrl) {
        StringBuilder html = new StringBuilder();
        try (Scanner scanner = new Scanner(
                new File(htmlUrl),
                StandardCharsets.UTF_8.name()) // 显式指定UTF-8
        ) {
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                html.append(line);
            }
        } catch (IOException e) {
            throw new ServiceException("读取HTML文件失败!");
        }
        return html.toString();
    }

    @Override
    public String changeData(String handbook, BasicInformationResponse b) {
        List<SysDictData> sysDictData = sysDictDataMapper.selectDictDataList(new SysDictData());
        Map<String, Object> dt = new HashMap<>();
        if (b.getBasicInformation().getFj() != null) {
            String[] split = b.getBasicInformation().getFj().split(",");
            for (int i = 0; i < split.length; i++) {
                dt.put("{{fjimg"+i+"}}",
                        Paths.get(RuoYiConfig.getProfile() + StringUtils.substringAfter(split[i], Constants.RESOURCE_PREFIX)).toUri().toString());
            }
        }
        dt.put("{{name}}", b.getBasicInformation().getName());
        dt.put("{{ztze}}", b.getBasicInformation().getZtze());
        dt.put("{{xmbq}}", b.getBasicInformation().getLabel());
        dt.put("{{prioritize}}", b.getBasicInformation().getPrioritize());
        dt.put("{{xzfl}}", basicInformationService.getDictLabel("xzfl", String.valueOf(b.getBasicInformation().getXzfl()), sysDictData));
        dt.put("{{jsms}}", basicInformationService.getDictLabel("jsms", String.valueOf(b.getBasicInformation().getJsms()), sysDictData));
        dt.put("{{ssgnq}}", basicInformationService.getDictLabel("ssgnq", String.valueOf(b.getBasicInformation().getSsgnq()), sysDictData));

        dt.put("{{zjzmj}}", b.getPlanInformation().getZjzmj());
        dt.put("{{zydmj}}", b.getPlanInformation().getZydmj());
        dt.put("{{bzcjzmj}}", b.getPlanInformation().getBzcjzmj());
        dt.put("{{zgjzgd}}", b.getPlanInformation().getZgjzgd());
        dt.put("{{jzds}}", b.getPlanInformation().getJzds());
        dt.put("{{zgjzcs}}", b.getPlanInformation().getZgjzcs());
        dt.put("{{fhdj}}", b.getPlanInformation().getFhdj());
        dt.put("{{jdctcw}}", b.getPlanInformation().getJdctcw());
        dt.put("{{fjdctcw}}", b.getPlanInformation().getFjdctcw());

        dt.put("{{yczmj}}", b.getQyrzInformation().getYczmj());
        dt.put("{{kzczmj}}", b.getQyrzInformation().getKzczmj());
        dt.put("{{gycfpjzj}}", b.getQyrzInformation().getGycfpjzj());
        dt.put("{{pjwyf}}", b.getQyrzInformation().getGycfpjwyf());

        // 动态替换所有模板变量
        for (Map.Entry<String, Object> entry : dt.entrySet()) {
            if (handbook.contains(entry.getKey())) {
                handbook = handbook.replace(entry.getKey(), entry.getValue() != null ? entry.getValue().toString() : "/");
            }
        }
        return handbook;
    }

    /**
     * 通过主键查询单条数据
     */
    @Override
    public GyslProjectHandbook getData(Serializable id) {
        GyslProjectHandbook byId = getById(id);
        byId.setProjectName(baseMapper.getProjectName(Arrays.asList(byId.getXmId().split(","))));
        return byId;
    }
}

