package com.bcxin.backend.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bcxin.backend.dao.mapper.SignatureQueuesDocumentMapper;
import com.bcxin.backend.entity.SignatureQueuesBazgz;
import com.bcxin.backend.entity.SignatureQueuesDocument;
import com.bcxin.backend.service.SignatureService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <b> 签章业务相关 </b>
 * @author ZXF
 * @create 2024/11/20 0020 18:14
 * @version
 * @注意事项 </b>
 */
@Slf4j
@Service
public class SignatureServiceImpl implements SignatureService {

    @Value("${myapps.storage.root}")
    String rootPath;
    @Value("${myapps.signature.api}")
    String api;
    @Value("${myapps.signature.appid}")
    String appid;
    @Value("${myapps.signature.sealno}")
    String sealno;

    //签章接口（单文档单章 支持PDF|OFD）
    private static final String STAMPFILE = "/channel/stampFile";
    //4.2.2.签章接口（不同文档不同章 支持PDF|OFD）
    private static final String FLEXIBLESEALFILE = "/channel/flexibleSealFile";
    //验章接口（支持PDF|OFD）
    private static final String VERIFYFILE = "/channel/verifyFile";

//    @Autowired
//    private SignatureQueuesBazgzMapper signatureQueuesBazgzMapper;
    @Autowired
    private SignatureQueuesDocumentMapper signatureQueuesDocumentMapper;

    /**
     * <b> 文书签章业务 </b>
     * @author ZXF
     * @create 2024/11/20 0020 17:33
     * @version
     * @注意事项 </b>
     */
    @Override
    public void documentSignature() {
        QueryWrapper<SignatureQueuesDocument> queryWrapper = new QueryWrapper<>();
        List<String> statusList = new ArrayList<>();
        statusList.add("0");
        statusList.add("3");
        queryWrapper.in("status", statusList);
        queryWrapper.last("limit 300");
        List<SignatureQueuesDocument> documentList = signatureQueuesDocumentMapper.selectList(queryWrapper);
        for (SignatureQueuesDocument document: documentList) {
            document.setStatus("2");
            Result ret = verifySignature(document.getFile_url(),document.getBusiness_name());
            if("200".equals(ret.status)){
                JSONObject dataJson = JSONObject.parseObject(JSON.toJSONString(ret.data));
                String result = dataJson.getString("result");
                if("FALSE".equals(result)){
                    //根据接口返回结果更新数据库
                    ret = sendSignature(document.getStamp_xy(), document.getFile_url(),document.getBusiness_name());
                    if("200".equals(ret.status)){
                        File file = JSONObject.parseObject(JSON.toJSONString(ret.data),File.class);
                        //base64文件流写入原文件地址
                        try {
                            if(StringUtils.isEmpty(file.fileB64)){
                                throw new IOException("文件不存在");
                            }
                            base64ToFile(file.fileB64,rootPath+document.getFile_url());
                            document.setStatus("1");
                        } catch (IOException e) {
                            document.setProcessed_result(e.getMessage());
                        }
                    }
                }else{
                    //如果文件已存在章，不重复盖章
                    document.setStatus("1");
                }
            }

            document.setProcessed_result(ret.getMessage());
            document.setLastmodified(new Date());
            signatureQueuesDocumentMapper.updateById(document);
        }

    }

    private static void base64ToFile(String base64String,String filePath) throws IOException {
        // 解码Base64字符串
        byte[] decodedBytes = Base64.decode(base64String);
        // 将字节数组写入文件
        Path path = Paths.get(filePath);
        Files.write(path, decodedBytes);
    }

    /**
     * <b> 资格证签章业务 </b>
     * @author ZXF
     * @create 2024/11/20 0020 17:33
     * @version
     * @注意事项 </b>
     */
    @Override
    public void bazgzSignature() {
        QueryWrapper<SignatureQueuesBazgz> queryWrapper = new QueryWrapper<>();
        List<String> statusList = new ArrayList<>();
        statusList.add("0");
        statusList.add("3");
        queryWrapper.in("status", statusList);
        queryWrapper.last("limit 300");
        /*List<SignatureQueuesBazgz> bazgzList = signatureQueuesBazgzMapper.selectList(queryWrapper);
        for (SignatureQueuesBazgz bazgz: bazgzList) {
            //根据接口返回结果更新数据库
            String ret = sendSignature(bazgz.getStamp_xy(), bazgz.getFile_url());
            bazgz.setProcessed_result(ret);
            bazgz.setLastmodified(new Date());
            bazgz.setStatus("4");
            signatureQueuesBazgzMapper.updateById(bazgz);
        }*/

    }

    /**
     * <b> 京通靓证同步业务 </b>
     * @author ZXF
     * @create 2024/11/20 0020 17:33
     * @version
     * @注意事项 </b>
     */
    @Override
    public void syncJT(){
        //成功的并且未同步的记录
        QueryWrapper<SignatureQueuesBazgz> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "1");
        queryWrapper.isNull("jt_code");
        queryWrapper.last("limit 300");
//        List<SignatureQueuesBazgz> bazgzList = signatureQueuesBazgzMapper.selectList(queryWrapper);
        //TODO 调用接口
        /*for (SignatureQueuesBazgz bazgz: bazgzList) {
            SignatureData data = JSONObject.parseObject(bazgz.getData(),SignatureData.class);
            String pdf =bazgz.getFile_url();
            String phone =bazgz.getHead_phone();

            bazgz.setIs_sync_jt(1);
            signatureQueuesBazgzMapper.updateById(bazgz);

        }*/
    }


    /**
     * <b> 签章业务 </b>
     * @author ZXF
     * @create 2024/11/20 0020 17:33
     * @version
     * @注意事项 </b>
     */
    private Result sendSignature(String stamp_xy, String file_path, String file_name){
        //TODO 调用接口
        try {
            String[] xyArr = stamp_xy.split(",");
            JSONObject json = new JSONObject();
            json.put("appId", appid);
            json.put("file", new File(file_name,Base64.encode(FileUtil.file(file_path)), "pdf",file_name+" 签章"));
            JSONObject seal = new JSONObject();
            seal.put("sealInfo", new SealInfo(sealno,"FALSE"));
            JSONObject ruleInfo = new JSONObject();
            ruleInfo.put("version", "1.0");
            ruleInfo.put("ruleId", "");
            ruleInfo.put("ruleType", "RECTANGLE");//RECTANGLE-坐标签章、KEYWORD-关键字签章、ACROSS-骑缝章签章（三选一）
            ruleInfo.put("rectangleRule", new RectangleRule(xyArr[0],xyArr[1],xyArr[2],xyArr[3],xyArr[3]));//印章坐标:page 页码，left 左，right 右，top 上，bottom 下
            seal.put("ruleInfo", ruleInfo);
            json.put("seal", seal);
            String ret = HttpUtil.post(api+STAMPFILE, json.toJSONString());
            log.info("====> 文书签章定时任务开始.sendSignature.ret：" + ret);
            if (StringUtils.isEmpty(ret)) {
                return Result.fail("接口请求失败：返回空");
            }
            return JSON.parseObject(ret,Result.class);
        } catch (Exception e){
            log.info("====> 签章业务定时任务开始.sendSignature message:"+e.getMessage());
            return Result.fail("接口请求异常："+e.getMessage());
        }
    }

    /**
     * <b> 验章业务 </b>
     * @author ZXF
     * @create 2024/11/20 0020 17:33
     * @version
     * @注意事项 </b>
     */
    private Result verifySignature(String file_path, String file_name){
        //TODO 调用接口
        try {
            JSONObject json = new JSONObject();
            json.put("appId", appid);
            json.put("file", new File(file_name,Base64.encode(FileUtil.file(file_path)), "pdf",file_name+" 签章"));
            String ret = HttpUtil.post(api+VERIFYFILE, json.toJSONString());
            log.info("====> 文书验章定时任务开始.verifySignature.ret：" + ret);
            if (StringUtils.isEmpty(ret)) {
                return Result.fail("接口请求失败：返回空");
            }
            return JSON.parseObject(ret,Result.class);
        } catch (Exception e){
            log.info("====> 文书验章定时任务开始.verifySignature message:"+e.getMessage());
            return Result.fail("接口请求异常："+e.getMessage());
        }
    }

    @Data
    public static class Result {
        private String status;
        private String message;
        private Object data;

        public Result(String status,String message){
            this.status = status;
            this.message = message;
            this.data = null;
        }
        public static Result fail(String message){
            return new Result("300",message);
        }
    }

    @Data
    public static class File {
        private String title;
        private String fileB64;
        private String filePath;
        private String fileType;
        private String templateData;
        private String classify;
        private String fileDesc;

        public File(String title, String fileB64, String fileType,String fileDesc){
            this.title = title;
            this.fileB64 = fileB64;
            this.fileType = fileType;
            this.fileDesc = fileDesc;
        }
    }

    @Data
    public static class RectangleRule {
        private String page;
        private String bottom;
        private String top;
        private String left;
        private String right;
        private String moveType;
        private JSON offset;

        public RectangleRule(String page,String left,String right,String top,String bottom){
            this.page = page;
            this.bottom = bottom;
            this.top = top;
            this.left = left;
            this.right = right;
        }
    }

    @Data
    public static class SealInfo {
        private String sealId;
        private String timeStamp;
        private String algo;

        public SealInfo(String sealId, String timeStamp){
            this.sealId = sealId;
            this.timeStamp = timeStamp;
            this.algo = "SM3withSM2";
        }
    }

    @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 certificatefrom;
        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;
    }
}
