package com.bcxin.backend.domain.services.impls;

import cn.hutool.core.util.ObjectUtil;
import com.bcxin.backend.domain.services.ConvertService;
import com.bcxin.backend.domain.syncs.dtos.SharedConvertDto;
import com.bcxin.backend.domain.utils.PDFUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;
@Slf4j
@Service
public class ConvertServiceImpl implements ConvertService {

    @Value("${myapps.storage.root}")
    String rootPath;

    /**
     * <b> html转pdf </b>
     * 使用openhtmltopdf技术
     * @author ZXF
     * @create 2022/10/26 0026 16:36
     * @version
     * @注意事项 </b>
     */
    public String execConvertHtmltopdfForTemp(SharedConvertDto convertDto) throws IOException {
        StopWatch stopWatch = new StopWatch();

        Exception lastException = null;
        stopWatch.start();
        try {
            if (StringUtils.isEmpty(convertDto.getTempUrl()) || ObjectUtil.isEmpty(convertDto.getFormData())) {
                return null;
            }
            JSONObject data = JSONObject.fromObject(convertDto.getFormData());
            String pdfPath = ObjectUtil.isEmpty(data.get("unSignaturePDF")) ? "" : data.get("unSignaturePDF") + "";
            if (StringUtils.isEmpty(pdfPath)) {
                return null;
            }
            String pdfFilePath = rootPath + pdfPath;
            File pdfFile = new File(pdfFilePath);
            if (!pdfFile.getParentFile().exists()) {
                pdfFile.getParentFile().mkdirs();
            }
            PDFUtils.generatePdfByOpenhtmltopdf(convertDto.getTempUrl(), pdfFilePath, convertDto.getFormData());
            pdfFile = new File(pdfFilePath);
            if (pdfFile.length() == 0) {
                pdfFile.delete();
                return null;
            }
            String newPath = pdfFilePath.replace(".temp", ".pdf");
            File newFile = new File(newPath);
            //重命名这个路径的文件
            boolean flag = pdfFile.renameTo(newFile);
            if (!flag) {
                pdfFile.delete();
                return null;
            }
            return newPath;
        } catch (Exception ex) {
            stopWatch.stop();
            log.error("====> HTML(url={},data={})转为PDF异常; 耗时{}秒",
                    convertDto.getTempUrl(),
                    convertDto.getFormData(),
                    stopWatch.getTotalTimeSeconds());
            lastException = ex;
            throw ex;
        } finally {
            if (lastException != null) {
                stopWatch.stop();
                log.warn("====> HTML(url={},data={})转为PDF成功; 耗时{}秒",
                        convertDto.getTempUrl(),
                        convertDto.getFormData(),
                        stopWatch.getTotalTimeSeconds());
            }
        }
    }

    /**
     * <b> 遍历临时目录下的pdf，取第一个剪切到in目录 </b>
     * @param convertDto 里面就传临时目录路径
     * @return null,剩余文件个数,文件名
     * @author ZXF
     * @create 2023/01/07 0007 11:14
     * @version
     * @注意事项 </b>
     */
    public String existsPdfCopy(SharedConvertDto convertDto) {
        int count = 80;

        StringBuilder trace = new StringBuilder();
        try {
            trace.append("begin;");
            if (convertDto.getFormData() != null) {
                count = Integer.parseInt(String.valueOf(convertDto.getFormData()));
            }
            if (StringUtils.isEmpty(convertDto.getTempUrl())) {
                return null;
            }
            trace.append("step1;");
            //临时目录
            String tempFilePath = rootPath + convertDto.getTempUrl();
            trace.append("step2;");
            String inFilePath = rootPath + convertDto.getTempUrl().replace("/temp", "/in");
            trace.append("step3;");
            File tempFile = new File(tempFilePath);
            trace.append("step4;");
            boolean exists = tempFile.exists();
            log.error("=======> existsPdfCopy.tempFile:{}-exists={};inFilePath={},count={}", tempFilePath, exists, inFilePath, count);

            if (!exists) {
                return null;
            }
            trace.append("step5;");
            //in目录
            File inFile = new File(inFilePath);
            if (!inFile.exists()) {
                inFile.mkdirs();
            }
            trace.append("step6;");
            File[] fi = inFile.listFiles();
            if (fi != null && fi.length > 20) {
                log.error("=======> 签章业务：剪切文件到指定目录异常，剩余文件超20个，打回;count={}", count);
                return null;
            }
            trace.append("step7;");
            File[] fa = tempFile.listFiles();
            int pCount = 0;
            trace.append("step8;");
            //新建一个String数组用于存放所有文件名
            List<String> list = Lists.newArrayList();
            for (int i = 0; i < fa.length; i++) {
                if (list.size() > 50) {
                    log.error("=======> existsPdfCopy.i={}", i);
                    break;
                }

                if (fa[i].getName().contains(".pdf")) {
                    list.add(fa[i].getName());
                    pCount++;
                }
            }

            trace.append("step9;");
            if (list.size() == 0) {
                log.error("=======> 非预期情况; 累计的list信息为空:pCount={};count={}", pCount, count);
                return null;
            }
            //新建一个String数组用于存放所有文件名
            //收集剪切成功的
            List<String> usrlist = Lists.newArrayList();
            trace.append("step10;");
            //将临时目录下的pdf文件剪切到in目录下(覆盖已有的目标路径)
            for (String fileName : list) {
                try {
                    File temp = new File(tempFilePath + "/" + fileName);
                    if (!temp.exists()) {
                        log.error("非预期行为拷贝数据到待签章目录的时候; 文件({})突然找不到", temp.getPath());
                        continue;
                    }
                    Files.move(Paths.get(tempFilePath + "/" + fileName), Paths.get(inFilePath + "/" + fileName), StandardCopyOption.REPLACE_EXISTING);
                    usrlist.add(fileName);
                } catch (IOException e) {
                    log.error("=======> 签章业务：剪切文件到指定目录异常，文件名：" + fileName + "，ERROR：" + e.getMessage());
                }
            }

            trace.append("step11;");
            log.error("=======> 签章业务：剪切文件到指定目录异常，已剪切：{}个;list.count={}", usrlist.size(), list.size());
            StringBuilder result = new StringBuilder();
            for (String fileName : usrlist) {
                result.append(fileName);
                result.append(";");
            }
            trace.append("step12;");
            return "0," + result;
        } catch (Exception ex) {
            log.error("existsPdfCopy exception:{}", trace, ex);

            throw ex;
        }
    }

    public File[] findInFile(String tempUrl) {
        String inFilePath = rootPath + tempUrl.replace("/temp","/in");
        //in目录
        File inFile = new File(inFilePath);
        if (!inFile.exists()) {
            System.err.println("=======> existsPdfCopy.findInFile.inFile:null");
            return null;
        }
        File[] fi = inFile.listFiles();
        System.err.println("=======> existsPdfCopy.findInFile.fi:"+fi);
        if(fi.length == 0){
            System.err.println("=======> existsPdfCopy.findInFile.fi:null");
            return null;
        }
        return fi;
    }

    public void delInPDF(SharedConvertDto convertDto) {
        String inFilePath = rootPath + convertDto.getTempUrl().replace("/temp","/in");
        String outFilePath = rootPath + convertDto.getTempUrl().replace("/temp","/out");
        //in目录
        File inFile = new File(inFilePath);
        if (!inFile.exists()) {
            return;
        }
        //out目录
        File outFile = new File(outFilePath);
        if (!outFile.exists()) {
            return;
        }
        File[] ifi = inFile.listFiles();
        File[] ofi = outFile.listFiles();
        if (ifi.length!=0&&ofi.length!=0){
            String outFName = "";
            for (int i = 0; i < ofi.length; i++) {
                File fs = ofi[i];
                outFName = outFName + fs.getName();
            }

            if(StringUtils.isNotEmpty(outFName)){
                for (int i = 0; i < ifi.length; i++) {
                    File fs = ifi[i];
                    if(outFName.contains(fs.getName())){
                        if (fs.exists() && !fs.isDirectory()) {
                            fs.delete();
                        }
                    }
                }
            }
        }
    }

    public void delSetFtpFile(String tempUrl,String fileNames) {
        String inFilePath = rootPath + tempUrl.replace("/temp","/in");
        String outFilePath = rootPath + tempUrl.replace("/temp","/out");
        //in目录
        File inFile = new File(inFilePath);
        if (!inFile.exists()) {
            return;
        }
        //out目录
        File outFile = new File(outFilePath);
        if (!outFile.exists()) {
            return;
        }
        File[] ifi = inFile.listFiles();
        if (ifi.length!=0){
            for (int i = 0; i < ifi.length; i++) {
                File fs = ifi[i];
                if(fileNames.contains(fs.getName())){
                    if (fs.exists() && !fs.isDirectory()) {
                        fs.delete();
                    }
                }
            }
        }
        File[] ofi = outFile.listFiles();
        if (ofi.length!=0){
            for (int i = 0; i < ofi.length; i++) {
                File fs = ofi[i];
                if(fileNames.contains(fs.getName())){
                    if (fs.exists() && !fs.isDirectory()) {
                        fs.delete();
                    }
                }
            }
        }
    }

    /**
     * <b> 单独检索in目录0kb文件删除 </b>
     * @author ZXF
     * @create 2023/07/19 0019 10:46
     * @version
     * @注意事项 </b>
     */
    public void delInPDF(String tempUrl) {
        String inFilePath = rootPath + tempUrl.replace("/temp","/in");
        //in目录
        File inFile = new File(inFilePath);
        if (!inFile.exists()) {
            return;
        }
        File[] ifi = inFile.listFiles();
        for (int i = 0; i < ifi.length; i++) {
            File fs = ifi[i];
            if(fs.length()<5 && !fs.isDirectory()){
                fs.delete();
            }
        }
    }

    public String existsScanSignature(SharedConvertDto convertDto) {
        if(StringUtils.isEmpty(convertDto.getTempUrl())) {
            log.error("existsScanSignature判断的适合convertDto.getTemUrl={}", convertDto.getTempUrl());
            return null;
        }

        return PDFUtils.uploadFtpFile(convertDto.getTempUrl(),rootPath);
    }

    public String existsScanSignatureByDayFile(SharedConvertDto convertDto) {
        if(StringUtils.isEmpty(convertDto.getTempUrl())){
            return null;
        }
        return PDFUtils.uploadDayFile(convertDto.getTempUrl(),rootPath);
    }
}
