package com.bcxin.backend.domain.signature.service.impls;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bcxin.backend.core.utils.ExceptionUtils;
import com.bcxin.backend.domain.models.SignatureQueuesDTO;
import com.bcxin.backend.domain.repositories.SignatureQueuesRepository;
import com.bcxin.backend.domain.services.impls.ConvertServiceImpl;
import com.bcxin.backend.domain.signature.service.SignatureToPDFService;
import com.bcxin.backend.domain.syncs.dtos.SharedConvertDto;
import io.jsonwebtoken.lang.Collections;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SignatureToPDFServiceImpl implements SignatureToPDFService {

    private final SignatureQueuesRepository signatureQueuesRepository;
    @Value("${myapps.domain.url}")
    String urlHead;
    @Value("${myapps.signature.tempPDF}")
    String tempPDF;
    @Value("${myapps.signature.mobanPDF}")
    String mobanPDF;
    @Value("${myapps.signature.cgiApi}")
    String cgiApi;
    @Autowired
    private ConvertServiceImpl convertService;

    @Autowired
    @Qualifier("primaryJdbcTemplate")
    protected JdbcTemplate jdbcTemplate;

    public SignatureToPDFServiceImpl(SignatureQueuesRepository signatureQueuesRepository) {
        this.signatureQueuesRepository = signatureQueuesRepository;
    }

    @Override
    public void cerPDF() {
        //后执行要创建签章中业务的逻辑
        createPDF();
    }

    /**
     * <b> 激活电子印章签验接口服务器完成签章 </b>
     * @author ZXF
     * @create 2022/11/21 0021 10:44
     * @version
     * @注意事项 </b>
     */
    private boolean activateXMPSignQuicklyExCGI() {
        StringBuilder sb = new StringBuilder();
        try {
            JSONObject json = new JSONObject();
            json.put("service", "wss://127.0.0.1:8800");
            json.put("sn", "2171101001009256");
            json.put("pin", "88888888");
            json.put("in", "/data/share/in");
            json.put("out", "/data/share/out");
            JSONArray arr = new JSONArray();
            JSONObject pos = new JSONObject();
            pos.put("centerX", 405);
            pos.put("centerY", 312);
            pos.put("page", 1);
            arr.add(pos);
            json.put("signOnPos", arr);
            String ret = HttpUtil.post(cgiApi, json.toJSONString());
            log.info("====> 电子签章定时任务开始.activateXMPSignQuicklyExCGI.ret：" + ret);
            if (StringUtils.isEmpty(ret)) {
                return false;
            }
            JSONObject result = JSON.parseObject(ret.replace("#", ""));
            if ("1".equals(String.valueOf(result.get("code")))) {
                return true;
            }
            return false;
        } catch (Exception e){
            log.info("====> xxxxxxxx 电子签章定时任务开始.activateXMPSignQuicklyExCGI message:"+e.getMessage());
        }
        return false;
    }

    /**
     * <b> 批量生成pdf文件 </b>
     * @author ZXF
     * @create 2022/10/31 0031 13:33
     * @version
     * @注意事项 </b>
     */
    private void createPDF() {
        //1.查询签章队列表需要签章的数据
        Page<SignatureQueuesDTO> pageQueues = signatureQueuesRepository.pageQueues(0, PageRequest.of(0, 300));
        List<SignatureQueuesDTO> queues = pageQueues.getContent();
        //Collection<SignatureQueuesDTO> queues = pageQueues.getContent();
        if (Collections.isEmpty(queues)) {
            return;
        }
        for (SignatureQueuesDTO queuesDTO:queues) {
            accept(queuesDTO);
        }
    }

    private void accept(SignatureQueuesDTO queue) {
        Long a = System.currentTimeMillis();
        SignatureData data = JSONObject.parseObject(queue.getData(),SignatureData.class);
        //先将文件命名为.temp
        data.setUnSignaturePDF(tempPDF+"/"+System.currentTimeMillis()+"queueId_"+queue.getId()+".temp");
        String toDay = data.getFzDate();
        if(StringUtils.isEmpty(toDay)){
            toDay = DateUtil.today();
        }
        data.setZYear(toDay.split("-")[0]);
        data.setZMonth(toDay.split("-")[1]);
        data.setZDay(toDay.split("-")[2]);
        data.setHeadphoto(data.getHeadphoto().startsWith("http")?data.getHeadphoto():urlHead+data.getHeadphoto());

        String result = "";
        SharedConvertDto sharedConvertDto = new SharedConvertDto();
        sharedConvertDto.setTempUrl(queue.getTemplate_url());
        sharedConvertDto.setFormData(data);
        if(!doesFileExist(data.getHeadphoto())){
            //失败
            signatureQueuesRepository.updateSignature(2,new Date(),"PDF生成失败：无头像信息",queue.getId());
            log.info("====> 电子签章定时任务开始.createPDF.accept.单次业务：002：fail：无头像信息");
        }
        try {
            //最终输出为.pdf文件，主要是为了避免pdf 0kb时就被剪切走
            result = convertService.execConvertHtmltopdfForTemp(sharedConvertDto);
        } catch (IOException e) {
            result = "";
            log.error("====> 电子签章定时任务开始.createPDF.accept.pdf生成异常："+e.getMessage());
        }
        if(StringUtils.isNotEmpty(result)){
            //成功
            signatureQueuesRepository.updateSignature(3,new Date(),"PDF已生成待签章",queue.getId());
        }else{
            //失败
            signatureQueuesRepository.updateSignature(2,new Date(),"PDF生成失败",queue.getId());
        }
        log.info("====> 电子签章定时任务开始.createPDF.accept.单次生成文件耗时："+(System.currentTimeMillis()-a));
    }

    public static boolean doesFileExist(String urlString) {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()){
            URL url = new URL(urlString);
            URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
            HttpGet HttpGet = new HttpGet(uri);
            try (CloseableHttpResponse resp = httpClient.execute(HttpGet)) {
                return (resp.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK);
            }
        } catch (Exception ex) {
            return false;
        }
    }

    public void delInPDF(){
        SharedConvertDto sharedConvertDto = new SharedConvertDto();
        sharedConvertDto.setTempUrl(tempPDF);
        convertService.delInPDF(sharedConvertDto);
    }

    @Override
    public void signQuicklyExCGI() {
        Long a = System.currentTimeMillis();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("tempUrl", tempPDF);
        jsonObject.put("formData", 230);
        try {
            //到文件夹剪切一个文件到out目录
            SharedConvertDto sharedConvertDto = new SharedConvertDto();
            String tempUrl = jsonObject.getString("tempUrl");
            String formData = jsonObject.getString("formData");
            sharedConvertDto.setTempUrl(tempUrl);
            sharedConvertDto.setFormData(formData);
            new Thread(()->{
                try {
                    //先检索in目录存在的删除
                    convertService.delInPDF(sharedConvertDto);
                } catch(Exception e) {
                    log.error("====> 电子签章定时任务开始.signQuicklyExCGI签章前比对in文件删除："+ e.getMessage());
                }
            }).start();
            //剪切文件到in目录下
            convertService.existsPdfCopy(sharedConvertDto);
            //每次盖章前先清除0kb文件
            convertService.delInPDF(tempPDF);
            //先触发对需要签章目录下文件进行签章
            activateXMPSignQuicklyExCGI();
            new Thread(()->{
                try {
                    //先检索in目录存在的删除
                    convertService.delInPDF(sharedConvertDto);
                } catch(Exception e) {
                    log.error("====> 电子签章定时任务开始.signQuicklyExCGI签章后比对in文件删除："+ e.getMessage());
                }
            }).start();
            log.info("====> 电子签章定时任务开始.signQuicklyExCGI.签章接口耗时："+(System.currentTimeMillis()-a));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void changeStatus() {
        String updateSql = "update obpm2_security.signature_queues set status = '0' where status = '3' and TIMESTAMPDIFF(HOUR, last_processed_time, NOW()) > 3";
        jdbcTemplate.update(updateSql);
    }

    public void scan() {
        StringBuilder sb = new StringBuilder();
        try {
            Long a = System.currentTimeMillis();
            JSONObject jsonObject = new JSONObject();
            String pdfFile = "/uploads/pdf/dianziqianzhang/out";
            jsonObject.put("tempUrl", pdfFile);
            jsonObject.put("formData", null);
            SharedConvertDto sharedConvertDto = new SharedConvertDto();
            sharedConvertDto.setTempUrl(pdfFile);
            sharedConvertDto.setFormData(null);
            String result = convertService.existsScanSignature(sharedConvertDto);
            if (StringUtils.isEmpty(result)) {
                log.info("====> 电子签章定时任务开始.scan.result：空");
                return;
            }
            log.info("====> 电子签章定时任务开始.scan.批量上传ftp结束耗时：" + (System.currentTimeMillis() - a));
            JSONObject json = JSONObject.parseObject(result);
            Object success = json.get("success");
            Object fail = json.get("fail");
//            String successQidS = "";
//            String failQidS = "";
            List<Long> failList = null;
            String successFile = "";
            String failFile = "";
            if (success != null){
                successFile = (String) success;//queueId_134147.pdf,queueId_134148.pdf,queueId_134149.pdf
                /*if(StringUtils.isNotEmpty(successFile)){
                    successQidS = "(" + successFile.replace(".pdf", "'").replace("queueId_", "'") + ")";
                }*/
            }
            if (fail != null){
                failFile = (String) fail;//queueId_134147.pdf,queueId_134148.pdf,queueId_134149.pdf
                if(StringUtils.isNotEmpty(failFile)){
//                    failQidS = "(" + failFile.replace(".pdf", "'").replace("queueId_", "'") + ")";
                    List<Long> failS = Arrays.stream(failFile.replace(".pdf", "")
                            .split("queueId_")[1].split(",")).map(ii->Long.parseLong(ii)).collect(Collectors.toList());
                    if(failS.size()>0){
                        failList = failS;
                    }
                }
            }
            String fileNames = successFile+failFile;
            new Thread(()->{
                try {
                    //只要ftp有跑过的都要比对删除
                    convertService.delSetFtpFile(tempPDF,fileNames);
                } catch(Exception e) {
                    log.error("====> 电子签章定时任务开始.scan.ftp操作过的文件删除："+ e.getMessage());
                }
            }).start();

            if (StringUtils.isNotEmpty(successFile)) {
                String updateSql;
                //成功
                String[] successSplit = successFile.split(",");
                for (String string : successSplit) {
                    String successFilePath = pdfFile+"/"+string;
                    Long id = Long.parseLong(string.split("queueId_")[1].replace(".pdf",""));
                    String business_id = signatureQueuesRepository.getBuId(id);
                    updateSql = "UPDATE tlk_certificate SET ITEM_SIGNATURED_PROCESSED_STATUS=\"2\",ITEM_LAST_SIGNATURED_PROCESSED_TIME=NOW(),ITEM_CERTIFICATEDATE=IFNULL(ITEM_CERTIFICATEDATE,NOW()),ITEM_LAST_SIGNATURED_PROCESSED_RESULT=\"完成\",ITEM_ATTACHMENT=\"" + successFilePath + "\" WHERE ID=\"" + business_id + "\";";
                    jdbcTemplate.update(updateSql);
                    signatureQueuesRepository.updateSignature(1, new Date(), "成功", id);
                }
            }
            if (failList != null){
                signatureQueuesRepository.updateSignatures(2, new Date(), "未成功签章", failList);
            }
            log.info("====> 电子签章定时任务开始.scan.50个PDF已签章文件存FTP耗时：" + (System.currentTimeMillis() - a));
        } catch (Exception e) {
            log.error("====> 电子签章定时任务开始.scan.updateSql error：" + ExceptionUtils.getStackMessage(e));
        }
    }

    @Data
    public static class SignatureData {
        private String name;
        private String address;
        private String headphoto;
        private String idcardno;
        private String year;
        private String month;
        private String day;
        private String certificateno;
        private String isSignature;
        //发证日期
        private String fzDate;
        private String zYear;
        private String zMonth;
        private String zDay;
        private String signatureImg;
        //未签章pdf存储路径
        private String unSignaturePDF;
        //已签章pdf扫描路径
        private String signaturePDF;
    }

    /**
     * Restful 接口返回的资源对象
     *
     */
    @Data
    public static class Resource {
        private int errcode;
        private String errmsg;
        private Object data;
    }
}
