package com.jwipc.order.logic.impl;

import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.google.common.collect.Maps;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.extgstate.PdfExtGState;
import com.jwipc.api.dto.ESignFileResposeDTO;
import com.jwipc.api.esign.SignFileCreateCallBackLogic;
import com.jwipc.constant.SignProcessType;
import com.jwipc.order.dto.PurchaseOrderPrintDTO;
import com.jwipc.order.logic.PurchaseOrderLogic;
import com.jwipc.order.service.IPurchaseOrderService;
import com.jwipc.order.util.PrintOrderCreatePdfUtil;
import com.jwipc.prop.SysProp;
import com.jwipc.sys.client.DictClient;
import com.jwipc.sys.client.ESignClient;
import com.jwipc.sys.client.FileClient;
import com.jwipc.sys.client.dto.DictDTO;
import com.jwipc.sys.logic.FileLogic;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.jwipc.constant.SignProcessType.PURCHASE_ORDER;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service("PurchaseOrderSignFileCreateCallBackLogicImpl")
@RequiredArgsConstructor
public class PurchaseOrderSignFileCreateCallBackLogicImpl implements SignFileCreateCallBackLogic {
    private static final Logger log = LoggerFactory.getLogger(PurchaseOrderSignFileCreateCallBackLogicImpl.class);
    private final PurchaseOrderLogic purchaseOrderLogic;
    private final Configuration freemarkerConfig;
    private final FileClient fileClient;
    private final  FileLogic fileLogic;
    private final ESignClient eSignClient;
    private final DictClient dictClient;
    private final SysProp sysProp;
    private final IPurchaseOrderService purchaseOrderService;

    @Override
    public List<ESignFileResposeDTO> processor(Long businessId,Integer templateType) {
        final List<PurchaseOrderPrintDTO> printData = purchaseOrderLogic.getPrintData(businessId.toString());
        //单个订单签署
        String configValue = ResourceUtil.readUtf8Str("view/pc/order/purchaseOrder/pdf_template.ftl");
        configValue = configValue.replace("<#include \"../../base/base.ftl\">",
                "<#macro formatDateTime dateTime pattern><#if dateTime??><#assign formattedDateTime = " +
                        "dateTime?datetime(\"yyyy-MM-dd'T'HH:mm\")>${formattedDateTime?string(pattern)" +
                        "}</#if></#macro>");
        final PurchaseOrderPrintDTO purchaseOrderPrintDTO = printData.get(0);
        // 增加供应商是否小批量，选择对应模板 2025-10-10 陈天仕 新增
        Integer qualifiedSupplierAmount = purchaseOrderService.findQualifiedSupplier(purchaseOrderPrintDTO.getSupplierCode());
        if (qualifiedSupplierAmount > 0) {
            // 合格的供应商
            purchaseOrderPrintDTO.setSupplierState("1");
        } else {
            // 小批量供应商
            purchaseOrderPrintDTO.setSupplierState("0");
        }
        Template template = null;
        try {
            //需要多个
            template = new Template("emailTemplate", configValue, freemarkerConfig);
            final Map<String, Object> map = Maps.newHashMap();
            map.put("ctx", sysProp.getHostUrl());
            map.put("purchaseOrder", purchaseOrderPrintDTO);
            //取朗华的交货地址， 邓京术 2025-07-04
            List<DictDTO> dictDTOS = dictClient.getDicByType("delivery_address_usd");
            dictDTOS.stream().forEach(item ->{
                map.put("deliverAddress" + item.getName(), item.getCode());
            });
            String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
            //创建pdf空文件
            File file = fileClient.createFile(
                    "采购订单-" + purchaseOrderPrintDTO.getOrderCode() + "-" + IdWorker.getIdStr() + ".pdf");
            log.info("file{}", file.getPath());
//            PDFUtil.generatePdfFromHtml(html, file.getPath(), true, true);
            OutputStream outputStream = new FileOutputStream(file);
            ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(html.getBytes());
            String fontPath =  "/static/font/msyh.ttc,1";
            PrintOrderCreatePdfUtil.convertToPdf(tInputStringStream, fontPath, outputStream);
            tInputStringStream.close();
            outputStream.close();
//            File file1 = new File(StrUtil.concat(false, fileLogic.genDatePath().getKey(), File.separator, "采购订单-" + purchaseOrderPrintDTO.getOrderCode() + "-" + IdWorker.getIdStr() + ".pdf"));
            File file1 = new File(StrUtil.concat(false, fileLogic.genDatePath().getKey(), File.separator, file.getName()));
//            FileOutputStream fos = new FileOutputStream(file1);
//            try (FileOutputStream fos = new FileOutputStream(file);
//                 FileChannel channel = fos.getChannel()) {
//                // 尝试获得文件锁，避免其他进程或线程占用文件
////                FileLock lock = channel.lock();
//                try {
//                    fos.write(byteArray);
//                } finally {
//                    // 解锁
//                    lock.release();
//                }
//            }
            // 延迟等待文件释放，避免文件占用冲突
//            waitForFileRelease(file);
            // 再次打开文件并进行处理
            // 使用 PdfReader 和 PdfWriter 进行处理
            InputStream inputStream = new FileInputStream(file1);
            PdfReader reader = new PdfReader(inputStream);
            PdfWriter writer = new PdfWriter(file1);
            int numberOfPages = 0;
            try (PdfDocument pdfDoc = new PdfDocument(reader, writer)) {
                numberOfPages = pdfDoc.getNumberOfPages();
                for (int i = 1; i <= numberOfPages; i++) {
                    String footerText = "　　　　　　　　　　　　　　　　　　　　　　　第" + i + "页 共" + numberOfPages  + "页";
                    PdfPage page = pdfDoc.getPage(i);
                    PdfCanvas canvas = new PdfCanvas(page);
                    try {
                        PdfExtGState extGState = new PdfExtGState();
                        extGState.setFillOpacity(1f); // 设置填充透明度为0.05
                        double alpha = Math.toRadians(0); // 倾斜角度
                        double tanAlpha = Math.tan(alpha);
                        //可根据页面宽高设置水印
                        canvas.saveState()
                                .concatMatrix(1, tanAlpha, 0, 1, 0, 0)
                                .beginText()
                                .resetFillColorGray()
                                .setExtGState(extGState)
                                .moveText(195, 18)
                                //.setFontAndSize(PdfFontFactory.createFont("/static/font/simsun.ttf", "Identity-H"), 10)
                                .setFontAndSize(PdfFontFactory.createFont(fontPath, "Identity-H"), 10)
                                .showText(footerText)
                                .endText()
                                .restoreState();
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    } finally {
                        inputStream.close();
                    }
                }
            }

            //上传到e签宝
            ESignFileResposeDTO eSignFileResposeDTO = fileClient.uploadESignFile(file1);
            String fileKey = eSignClient.sendFileClient(eSignFileResposeDTO, fileClient.file2MultipartFile(file1));
            //插入fileKey
            eSignFileResposeDTO.setFileKey(fileKey);
            //返回文件总页数到前端，校验骑缝章的问题。 邓京术 2025-07-09
            eSignFileResposeDTO.setNumberOfPages(numberOfPages);
            List<ESignFileResposeDTO> eSignFileResposeDTOS = new ArrayList<>();
            eSignFileResposeDTOS.add(eSignFileResposeDTO);
            //返回list
            return eSignFileResposeDTOS;
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (TemplateException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public SignProcessType getProcessType() {
        return PURCHASE_ORDER;
    }
}