package org.jeecg.modules.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.app.dto.*;
import org.jeecg.modules.app.esign.comm.EsignHttpResponse;
import org.jeecg.modules.app.esign.exception.EsignDemoException;
import org.jeecg.modules.app.esign.fileAndTemplate.FileDemo;
import org.jeecg.modules.app.esign.sign.SignDemo;
import org.jeecg.modules.app.service.IESignService;
import org.jeecg.modules.system.app.dto.AppContractInfoDTO;
import org.jeecg.modules.system.app.dto.ContractSignDTO;
import org.jeecg.modules.system.app.entity.AppContractInfo;
import org.jeecg.modules.system.app.entity.AppContractSign;
import org.jeecg.modules.system.app.entity.AppOrder;
import org.jeecg.modules.system.app.entity.FamilyMembers;
import org.jeecg.modules.system.app.mapper.*;
import org.jeecg.modules.system.app.vo.ContractSignVO;
import org.jeecg.modules.system.entity.SysDepart;
import org.jeecg.modules.system.mapper.SysDepartMapper;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

import static com.alibaba.dashscope.utils.JsonUtils.gson;
import static org.jeecg.modules.app.esign.auth.ESignAuth.*;
import static org.jeecg.modules.app.esign.fileAndTemplate.TemplateDemo.*;
import static org.jeecg.modules.app.esign.members.MembersDemo.administrators;
import static org.jeecg.modules.app.esign.seal.SealDemo.*;
import static org.jeecg.modules.app.esign.sign.SignDemo.createByFile;

@Service
@Log4j2
public class ESignServiceImpl implements IESignService {
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private AppContractInfoMapper appAccountMapper;
    @Resource
    private SysDepartMapper sysDepartMapper;
    @Resource
    private AppOrderMapper orderMapper;
    @Resource
    private AppContractSignMapper appContractSignMapper;
    @Resource
    private FamilyMembersMapper familyMembersMapper;
    @Resource
    private AppSiteMapper appSiteMapper;
    private static final String NOTIFY_URL = "http://47.109.18.141:8080/jeecg-boot/app/esign/signCallback";
    private static final String REDIRECT_URL = "";
    private static final String NAME_MAIN_ORGANIZATION = "中数未来（海南）系统集成有限公司";
    private static final String MAIN_CARD_NUM = "91460105MAA9A6L75X";
    private static final String REMOTE_URL = "http://127.0.0.1:8080/jeecg-boot/sys/common/static/";
    private static final String[] PERSON_AUTH_MODES = {"PSN_MOBILE3"};
    private static final String[] WILLINGNESS_MODES = {"CODE_SMS"};
    private static final String[] ORG_AUTH_MODES = {"ORG_ALIPAY_CREDIT", "ORG_LEGALREP"};
    private static final int DEFAULT_EXPIRE_TIME = 86400000;
    @Override
    public boolean getUserIdentityInfo(String familyId) throws EsignDemoException {
        FamilyMembers familyMembers = familyMembersMapper.selectById(familyId);
        EsignHttpResponse getPsnIdentityInfo = getPsnIdentityInfo(familyMembers.getPhone());
        JsonObject getPsnIdentityInfoObject = gson.fromJson(getPsnIdentityInfo.getBody(), JsonObject.class);
        if(getPsnIdentityInfoObject.get("code").getAsString().equals("1435203")) return false;
        String realnameStatus =getPsnIdentityInfoObject.getAsJsonObject("data").get("realnameStatus").getAsString();//授权状态authorizeUserInfo
        String psnId =getPsnIdentityInfoObject.getAsJsonObject("data").get("psnId").getAsString();
        familyMembers.setPsnId(psnId);
        familyMembersMapper.updateById(familyMembers);
        return realnameStatus.equals("1");
    }

    @Override
    public String getAuthUrl(String familyId) throws EsignDemoException {
//        FamilyMembers familyMembers = familyMembersMapper.selectById(familyId);
        GetPsnAuthUrlDTO getPsnAuthUrlDTO = new GetPsnAuthUrlDTO();
//        GetPsnAuthUrlDTO.PsnAuthConfig pncAuthConfig = new GetPsnAuthUrlDTO.PsnAuthConfig().setPsnAccount(familyMembers.getPhone());
        GetPsnAuthUrlDTO.PsnAuthConfig pncAuthConfig = new GetPsnAuthUrlDTO.PsnAuthConfig().setPsnAccount("17885674919");
        getPsnAuthUrlDTO.setPsnAuthConfig(pncAuthConfig);
        EsignHttpResponse getPsnAuthUrl = getPsnAuthUrl(getPsnAuthUrlDTO);
        JsonObject getPsnAuthUrlObject = gson.fromJson(getPsnAuthUrl.getBody(), JsonObject.class);
        if(getPsnAuthUrlObject.get("code").getAsString().equals("1450005")) throw new JeecgBootException("当前用户已实名");
        JsonObject data = getPsnAuthUrlObject.getAsJsonObject("data");
        return data.get("authShortUrl").getAsString();
    }

    @Override
    public boolean getOrgIdentityInfos(String orgCode) throws EsignDemoException {
        SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, orgCode));
        if(sysDepart == null) return false;
        EsignHttpResponse getOrgIdentityInfo = getOrgIdentityInfo(sysDepart.getDepartName());
        JsonObject getOrgIdentityInfoObject = gson.fromJson(getOrgIdentityInfo.getBody(), JsonObject.class);
        JsonElement dataElement = getOrgIdentityInfoObject.get("data");
        if (dataElement == null || !dataElement.isJsonObject()) {
            // 记录原始响应内容便于排查
            log.error("data字段解析失败，原始响应：{}", getOrgIdentityInfo.getBody());
            throw new JeecgBootException("未查询到授权信息");
        }
        JsonObject dataObj = dataElement.getAsJsonObject();
        String orgRealnameStatus = dataObj.get("realnameStatus").getAsString();
        String orgId = dataObj.get("orgId").getAsString();
        JsonObject jsonObject = dataObj.get("orgInfo").getAsJsonObject();
        String orgIDCardNum = jsonObject.get("orgIDCardNum").getAsString();
        sysDepart.setEsignOrgId(orgId);
        sysDepart.setOrgIdCardNum(orgIDCardNum);
        sysDepartMapper.updateById(sysDepart);
        return orgRealnameStatus.equals("1");
    }

    @Override
    public String getOrgAuthUrls(String orgCode,String phoneNumber) throws EsignDemoException {
        SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, orgCode));
        EsignHttpResponse getOrgAuthUrl = getOrgAuthUrl(sysDepart.getDepartName(),phoneNumber);
        JsonObject getOrgAuthUrlObject = gson.fromJson(getOrgAuthUrl.getBody(), JsonObject.class);
        return getOrgAuthUrlObject.getAsJsonObject("data").get("authUrl").getAsString();
    }

    @Override
    public boolean uploadContractTemplate(AppContractInfoDTO appContractInfoDTO) throws Exception {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String remoteUrl = appContractInfoDTO.getFilePath();
        String fileType = getFileExtension(appContractInfoDTO.getFilePath());
        if (fileType.isEmpty()) {
            throw new JeecgBootException("未指定文件类型");
        }
        EsignHttpResponse getUploadUrl = FileDemo.getUploadUrl(remoteUrl);
        JsonObject getUploadUrlJsonObject = gson.fromJson(getUploadUrl.getBody(), JsonObject.class);
        JsonObject data = getUploadUrlJsonObject.getAsJsonObject("data");
        //文件id后续发起签署使用
        String fileId =data.get("fileId").getAsString();
        String fileUploadUrl =data.get("fileUploadUrl").getAsString();
        System.out.println("获取文件id以及文件上传地址成功，文件id:"+fileId);
        System.out.println("上传链接:"+fileUploadUrl);
        EsignHttpResponse uploadFileResponse = FileDemo.uploadFile(fileUploadUrl,remoteUrl);
        JsonObject uploadFileResponseJsonObject = gson.fromJson(uploadFileResponse.getBody(), JsonObject.class);
        int errCode = uploadFileResponseJsonObject.get("errCode").getAsInt();
        System.out.println("文件上传成功，状态码:"+errCode);
        if (errCode == 0) {
            appAccountMapper.delete(Wrappers.<AppContractInfo>lambdaQuery()
                    .eq(AppContractInfo::getOrgCode, user.getOrgCode()));
            AppContractInfo appContractInfo = appAccountMapper.selectOne(Wrappers.<AppContractInfo>lambdaQuery()
                    .eq(AppContractInfo::getFileId, fileId));
            if(null != appContractInfo){
                appAccountMapper.deleteById(appContractInfo);
            }
            appAccountMapper.insert(new AppContractInfo()
                    .setOrgCode(user.getOrgCode())
                    .setFileId(fileId)
                    .setContractName(appContractInfoDTO.getContractName())
                    .setRemark(appContractInfoDTO.getRemark())
                    .setCreateBy(user.getId())
                    .setCreateTime(new Date())
                    .setUpdateTime(new Date())
                    .setUpdateBy(user.getId())
                    .setContractType(fileType)); // 新增文件类型字段
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createSign(String orderCode, String familyId){
        AppOrder appOrder = orderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery()
                .eq(AppOrder::getOrderCode, orderCode));

        AppContractInfo contractInfo = appAccountMapper.selectOne(Wrappers.<AppContractInfo>lambdaQuery()
                .eq(AppContractInfo::getOrgCode, appOrder.getOrgCode()).eq(AppContractInfo::getDelFlag, 0));
        SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery()
                .eq(SysDepart::getOrgCode, appOrder.getOrgCode()));

        if(null == contractInfo) throw new JeecgBootException("该商户未上传合同底稿");
        try {
            FamilyMembers familyMembers = familyMembersMapper.selectById(familyId);
            JsonObject dto = buildSignFlowDto(contractInfo, sysDepart, familyMembers);

            EsignHttpResponse response = createByFile(dto.toString());
            String signFlowId = extractSignFlowId(response);

            log.info("生成签署流程ID: {}", signFlowId);
            saveSignFlowRecord(signFlowId, appOrder, familyId);
            return signFlowId;
        } catch (EsignDemoException e) {
            log.error("签署流程创建失败，订单号: {}", orderCode, e);
            throw new JeecgBootException(e.getMessage());
        }

    }
    /**
     * 构建签署流程请求体
     */
    private JsonObject buildSignFlowDto(AppContractInfo contractInfo,
                                        SysDepart sysDepart,
                                        FamilyMembers familyMembers) throws EsignDemoException {
        JsonObject dto = new JsonObject();
        // 构建文档信息
        JsonArray docs = new JsonArray();
        JsonObject doc = new JsonObject();
        doc.addProperty("fileId", contractInfo.getFileId());
        doc.addProperty("fileName", contractInfo.getContractName() + "." + contractInfo.getContractType());
        docs.add(doc);
        dto.add("docs", docs);

        // 构建附件信息
        dto.add("attachments", docs);

        // 构建签署流程配置
        JsonObject signFlowConfig = new JsonObject();
        signFlowConfig.addProperty("signFlowTitle", contractInfo.getContractName());
        signFlowConfig.addProperty("signFlowExpireTime", System.currentTimeMillis() + DEFAULT_EXPIRE_TIME);
        signFlowConfig.addProperty("autoStart", true);
        signFlowConfig.addProperty("autoFinish", true);
        signFlowConfig.addProperty("identityVerify", true);

        // 签署配置
        JsonObject signConfig = new JsonObject();
        signConfig.addProperty("availableSignClientTypes", "1");
        signConfig.addProperty("showBatchDropSealButton", true);
        signFlowConfig.add("signConfig", signConfig);

        // 通知配置
        signFlowConfig.addProperty("notifyUrl", NOTIFY_URL);

        // 重定向配置
        JsonObject redirectConfig = new JsonObject();
        redirectConfig.addProperty("redirectUrl", REDIRECT_URL);
        signFlowConfig.add("redirectConfig", redirectConfig);

        // 认证配置
        JsonObject authConfig = new JsonObject();
        addStringArray(authConfig, "psnAvailableAuthModes", PERSON_AUTH_MODES);
        addStringArray(authConfig, "willingnessAuthModes", WILLINGNESS_MODES);
        addStringArray(authConfig, "orgAvailableAuthModes", ORG_AUTH_MODES);
        signFlowConfig.add("authConfig", authConfig);

        dto.add("signFlowConfig", signFlowConfig);

        // 发起人信息
        JsonObject signFlowInitiator = new JsonObject();
        JsonObject orgInitiator = new JsonObject();
        orgInitiator.addProperty("orgId", sysDepart.getEsignOrgId());

        JsonObject transactor = new JsonObject();
        transactor.addProperty("psnId", familyMembers.getPsnId());
//        transactor.addProperty("psnId", "630548cc4f954e7fad05210af02cee35");
        orgInitiator.add("transactor", transactor);

        signFlowInitiator.add("orgInitiator", orgInitiator);
        dto.add("signFlowInitiator", signFlowInitiator);

        // 签署人信息
        dto.add("signers", buildSigners(contractInfo, familyMembers,sysDepart.getEsignOrgId()));

        return dto;
    }

    private SignPositionGroup groupComponentPositions(JsonObject getComponentsInfoObject) {
        SignPositionGroup group = new SignPositionGroup();
        List<SignPositionGroup.ComponentPosition> merchant = new ArrayList<>();
        List<SignPositionGroup.ComponentPosition> customer = new ArrayList<>();

        JsonArray components = getComponentsInfoObject
                .getAsJsonObject("data")
                .getAsJsonArray("components");

        for (JsonElement element : components) {
            JsonObject component = element.getAsJsonObject();
            JsonObject componentSpecialAttribute = component
                    .getAsJsonObject("componentSpecialAttribute");
            String role = null;
            if (componentSpecialAttribute.has("signerRole")) {
                JsonElement roleElement = componentSpecialAttribute.get("signerRole");
                if (!roleElement.isJsonNull()) {
                    role = roleElement.getAsString();
                }
            }

            JsonObject position = component
                    .getAsJsonObject("componentPosition");

            int x = position.get("componentPositionX").getAsInt();
            int y = position.get("componentPositionY").getAsInt();
            int pageNum = position.get("componentPageNum").getAsInt();

            SignPositionGroup.ComponentPosition cp = new SignPositionGroup.ComponentPosition(x, y ,pageNum);

            if ("商户".equals(role)) {
                merchant.add(cp);
            } else if ("用户".equals(role)) {
                customer.add(cp);
            }
        }
        group.setMerchant(merchant);
        group.setCustomer(customer);
        return group;
    }

    /**
     * 构建签署人信息
     */
    private JsonArray buildSigners(AppContractInfo contractInfo, FamilyMembers familyMembers,String orgId) throws EsignDemoException {
        JsonArray signers = new JsonArray();
        EsignHttpResponse getComponentsInfo = getComponentsInfo(contractInfo.getDocTemplateId());
        JsonObject getComponentsInfoObject = gson.fromJson(getComponentsInfo.getBody(), JsonObject.class);
        System.err.println("查询模板详情返回："+getComponentsInfoObject);
        SignPositionGroup positionGroup = groupComponentPositions(getComponentsInfoObject);
        // 个人签署人
        JsonObject signer1 = new JsonObject();
        signer1.add("signConfig", buildSignConfig(1, 10));
        signer1.add("noticeConfig", buildNoticeConfig(""));
        signer1.addProperty("signerType", 0);
        // 签署人信息
        JsonObject psnSignerInfo = new JsonObject();
        psnSignerInfo.addProperty("psnAccount", familyMembers.getPhone());

        JsonObject psnInfo = new JsonObject();
        psnInfo.addProperty("psnName", familyMembers.getFullName());
        psnInfo.addProperty("psnIDCardNum", familyMembers.getIdentityCard());
        psnInfo.addProperty("psnIDCardType", "CRED_PSN_CH_IDCARD");
        psnSignerInfo.add("psnInfo", psnInfo);

        signer1.add("psnSignerInfo", psnSignerInfo);
        positionGroup.getCustomer().forEach(position -> {
            signer1.add("signFields", buildSignFields(contractInfo.getFileId(),
                    position.getX(), position.getY(),
                    100, 0, 0,false,"", position.getPageNum()));
        });
        // 企业签署人
        JsonObject signer2 = new JsonObject();
        signer2.addProperty("signerType", 1);
        JsonObject orgSignerInfo = new JsonObject();
        orgSignerInfo.addProperty("orgId", orgId);
        positionGroup.getMerchant().forEach(position -> {
            try {
                signer2.add("signFields", buildSignFields(contractInfo.getFileId(),
                        position.getX(),
                        position.getY(), 100, 0, 0,true,orgAuthorizedSeal(orgId),position.getPageNum()));
            } catch (EsignDemoException e) {
                throw new RuntimeException(e);
            }
        });
        signers.add(signer1);
        signers.add(signer2);
        return signers;
    }

    /**
     * 构建签署配置
     */
    private JsonObject buildSignConfig(int signOrder, int readingTime) {
        JsonObject signConfig = new JsonObject();
        signConfig.addProperty("forcedReadingTime", String.valueOf(readingTime));
        signConfig.addProperty("signOrder", signOrder);
        return signConfig;
    }

    /**
     * 构建通知配置
     */
    private JsonObject buildNoticeConfig(String noticeTypes) {
        JsonObject noticeConfig = new JsonObject();
        noticeConfig.addProperty("noticeTypes", noticeTypes);
        return noticeConfig;
    }

    /**
     * 构建签署区域
     */
    private JsonArray buildSignFields(String fileId,
                                      float x, float y,
                                      int size,
                                      int dateX,
                                      int dateY,
                                      boolean autoSign,
                                      String signature,
                                      int positionPage) {
        JsonArray signFields = new JsonArray();
        JsonObject field = new JsonObject();

        field.addProperty("fileId", fileId);
        field.addProperty("customBizNum", "自定义编码0001");
        field.addProperty("signFieldType", 0);

        // 签署配置
        JsonObject normalConfig = new JsonObject();
        normalConfig.addProperty("autoSign", autoSign);
        normalConfig.addProperty("freeMode", false);
        normalConfig.addProperty("movableSignField", false);
        normalConfig.addProperty("psnSealStyles", "0,1");
        normalConfig.addProperty("signFieldSize", String.valueOf(size));
        normalConfig.addProperty("signFieldStyle", 1);
        normalConfig.addProperty("assignedSealId", signature);

        // 位置配置
        JsonObject position = new JsonObject();
        position.addProperty("positionPage", positionPage);
        position.addProperty("positionX", x);
        position.addProperty("positionY", y);
        normalConfig.add("signFieldPosition", position);

        // 日期配置
        JsonObject dateConfig = new JsonObject();
        dateConfig.addProperty("dateFormat", "yyyy-MM-dd");
        dateConfig.addProperty("showSignDate", 1);
        dateConfig.addProperty("signDatePositionX", dateX);
        dateConfig.addProperty("signDatePositionY", dateY);

        field.add("normalSignFieldConfig", normalConfig);
        field.add("signDateConfig", dateConfig);

        signFields.add(field);
        return signFields;
    }

    /**
     * 提取签署流程ID
     */
    private String extractSignFlowId(EsignHttpResponse response) {
        JSONObject result = JSONObject.parseObject(response.getBody());
        if (result.getString("code").equals("1435002")) throw new JeecgBootException("该使用人未授权");
        if (result.getString("code").equals("1437328")) throw new JeecgBootException("该签署人账号：15120118404对应用户已存在个人信息，传入的指定签署人信息与已有个人信息不一致，请先确认信息是否准确：姓名张涛,大陆身份证522129200105265514");
        return result.getJSONObject("data").getString("signFlowId");
    }

    /**
     * 保存签署流程记录
     */
    private void saveSignFlowRecord(String signFlowId, AppOrder appOrder, String familyId) {
        AppContractSign appContractSign = appContractSignMapper.selectOne(Wrappers.<AppContractSign>lambdaQuery()
                .eq(AppContractSign::getOrderId, appOrder.getId())
                .eq(AppContractSign::getFamilyId, familyId));
        appContractSign.setSignFlowId(signFlowId);
        appContractSignMapper.updateById(appContractSign);
    }

    /**
     * 添加字符串数组到JSON对象
     */
    private void addStringArray(JsonObject parent, String key, String[] values) {
        JsonArray array = new JsonArray();
        for (String value : values) {
            array.add(value);
        }
        parent.add(key, array);
    }

    @Override
    public String getSignUrl(String signFlowId) throws EsignDemoException {
        AppContractSign appContractSign = appContractSignMapper.selectOne(Wrappers.<AppContractSign>lambdaQuery().eq(AppContractSign::getSignFlowId, signFlowId));
        if(null == appContractSign) throw new JeecgBootException("未找到该签署流程，请先发起签署");
        FamilyMembers familyMembers = familyMembersMapper.selectById(appContractSign.getFamilyId());
        SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, appContractSign.getOrgCode()));
        JSONObject signUrl = JSONObject.parseObject(SignDemo.signUrl(signFlowId,familyMembers.getPhone(),sysDepart.getDepartName()).getBody());
        return signUrl.getJSONObject("data").getString("shortUrl");
    }

    @Override
    public String createTemplate(String fileId) throws EsignDemoException {
        AppContractInfo appContractInfo = appAccountMapper.selectOne(Wrappers.<AppContractInfo>lambdaQuery().eq(AppContractInfo::getFileId, fileId));
        List<String> signerRoles = new ArrayList<>();
        signerRoles.add("商户");
        signerRoles.add("用户");
        DocTemplateDTO docTemplateDTO = new DocTemplateDTO()
                .setDocTemplateName(appContractInfo.getContractName())
                .setDocTemplateType(0)
                .setFileId(fileId)
                .setRedirectUrl(appContractInfo.getRedirectUrl())
                .setSignerRoles(signerRoles);
        /* 获取制作合同模板页面*/
        EsignHttpResponse getTemplateCreateUrl = getTemplateCreateUrl(docTemplateDTO);
        Gson gson = new Gson();
        JsonObject getTemplateCreateUrlObject = gson.fromJson(getTemplateCreateUrl.getBody(), JsonObject.class);
        String docTemplateCreateUrl = getTemplateCreateUrlObject.getAsJsonObject("data").get("docTemplateCreateUrl").getAsString();
        String docTemplateId = getTemplateCreateUrlObject.getAsJsonObject("data").get("docTemplateId").getAsString();
        System.err.println("制作合同模板的页面链接:"+docTemplateCreateUrl);
        System.err.println("合同模板id:"+docTemplateId);
        appContractInfo.setDocTemplateId(docTemplateId);
        appAccountMapper.updateById(appContractInfo);
        return docTemplateCreateUrl;
    }

    @Override
    public String editContract(String docTemplateId) throws EsignDemoException {
        AppContractInfo appContractInfo = appAccountMapper.selectOne(Wrappers.<AppContractInfo>lambdaQuery().eq(AppContractInfo::getDocTemplateId, docTemplateId));
        /* 获取编辑合同模板页面*/
        EsignHttpResponse getTemplateEditUrl = getTemplateEditUrl(docTemplateId,appContractInfo.getRedirectUrl());
        JsonObject getTemplateEditUrlObject = gson.fromJson(getTemplateEditUrl.getBody(), JsonObject.class);
        String docTemplateEditUrl = getTemplateEditUrlObject.getAsJsonObject("data").get("docTemplateEditUrl").getAsString();
        System.err.println("编辑合同模板的页面链接:"+docTemplateEditUrl);
        return docTemplateEditUrl;
    }

    @Override
    public List<Map<String,String>> fileDownloadUrl(String signFlowId) throws EsignDemoException {
        EsignHttpResponse esignHttpResponse = SignDemo.fileDownloadUrl(signFlowId);
        JsonObject jsonObject = gson.fromJson(esignHttpResponse.getBody(), JsonObject.class);
        JsonArray fileArray = jsonObject.getAsJsonObject("data").getAsJsonArray("files");
        List<Map<String, String>> result = new ArrayList<>();
        for (JsonElement element : fileArray) {
            JsonObject fileObj = element.getAsJsonObject();
            Map<String, String> fileMap = new HashMap<>();
            fileMap.put("fileId", fileObj.get("fileId").getAsString());
            fileMap.put("fileName", fileObj.get("fileName").getAsString());
            fileMap.put("downloadUrl", fileObj.get("downloadUrl").getAsString());
            result.add(fileMap);
        }
        return result;
    }

    @Override
    public List<AppContractInfo> queryContractInfo(String contractName) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if(null != contractName && !contractName.isEmpty()){
            return appAccountMapper.selectList(Wrappers.<AppContractInfo>lambdaQuery()
                    .like(AppContractInfo::getContractName,contractName).like(AppContractInfo::getOrgCode,user.getOrgCode()));
        }else {
            return appAccountMapper.selectList(Wrappers.<AppContractInfo>lambdaQuery().like(AppContractInfo::getOrgCode,user.getOrgCode()));
        }
    }

    @Override
    public List<SealInfoDTO> orgOwnSeal(String orgCode) {
        List<SealInfoDTO> sealInfoDTOLists = new ArrayList<>();
        List<SysDepart> sysDeparts = sysDepartMapper.selectList(Wrappers.<SysDepart>lambdaQuery().like(SysDepart::getOrgCode, orgCode));
        sysDeparts.forEach(sysDepart -> {
            if(sysDepart.getEsignOrgId() != null){
                // 调用API获取响应
                EsignHttpResponse response = orgOwnSealList(sysDepart.getEsignOrgId());

                // 解析JSON响应
                JsonObject result = gson.fromJson(response.getBody(), JsonObject.class);

                // 验证数据结构
                if (!result.has("data")) {
                    throw new JeecgBootException("响应数据中缺少'data'字段");
                }
                if(result.get("code").getAsInt() != 0){
                    return;
                }
                JsonObject data = result.getAsJsonObject("data");

                if (!data.has("seals")) {
                    throw new JeecgBootException("响应数据中缺少'seals'字段");
                }
                // 原始数据
                JsonArray seals = data.getAsJsonArray("seals");

                JsonArray filteredSeals = new JsonArray();
                for (JsonElement element : seals) {
                    JsonObject seal = element.getAsJsonObject();
                    if ("PUBLIC".equals(seal.get("sealBizType").getAsString())) {
                        filteredSeals.add(seal);
                    }
                }
                List<SealInfoDTO> sealInfoDTOList = gson.fromJson(filteredSeals, new TypeToken<List<SealInfoDTO>>(){}.getType());
                sealInfoDTOList.forEach(a ->{
                    a.setOrgCode(sysDepart.getOrgCode());
                    try {
                        // 调用接口获取授权信息
                        EsignHttpResponse response1 = orgSealsExternalAuth(sysDepart.getEsignOrgId(), a.getSealId());
                        JsonObject result1 = gson.fromJson(response1.getBody(), JsonObject.class);

                        // 检查 data 字段
                        if (!result1.has("data")) {
                            log.warn("授权信息中缺少 data 字段");
                            a.setIsStatus(false);
                            return;
                        }

                        JsonObject data1 = result1.getAsJsonObject("data");
                        if (!data1.has("sealAuthorizedInfos")) {
                            log.warn("授权信息中缺少 sealAuthorizedInfos 字段");
                            a.setIsStatus(false);
                            return;
                        }

                        // 遍历授权信息列表
                        JsonArray sealAuthorizedInfos = data1.getAsJsonArray("sealAuthorizedInfos");
                        boolean isValid = false;

                        for (JsonElement element : sealAuthorizedInfos) {
                            JsonObject info = element.getAsJsonObject();
                            String expireReason = info.get("expireReasonDescription").getAsString();
                            String status = info.get("statusDescription").getAsString();

                            if ("未失效".equals(expireReason) && "正常".equals(status)) {
                                isValid = true;
                                break;
                            }
                        }

                        // 设置 isStatus 字段
                        a.setIsStatus(isValid);

                    } catch (EsignDemoException | JsonSyntaxException e) {
                        log.error("处理印章授权状态失败，sealId: {}", a.getSealId(), e);
                        a.setIsStatus(false);
                    }
                });
                sealInfoDTOLists.addAll(sealInfoDTOList);
            }
        });
        return sealInfoDTOLists;
    }

    @Override
    public Boolean orgSealsExternal(String orgCode, String sealId) throws EsignDemoException {
        SysDepart sysDepart = sysDepartMapper.selectOne(Wrappers.<SysDepart>lambdaQuery().eq(SysDepart::getOrgCode, orgCode));
        EsignHttpResponse administrators = administrators(sysDepart.getEsignOrgId());
        JsonObject administratorsObject = gson.fromJson(administrators.getBody(), JsonObject.class);
        if(administratorsObject.get("code").getAsInt() == 1435203) throw new JeecgBootException("当前登录账号无操作权限！");
        JsonObject data = administratorsObject.getAsJsonObject("data");
        String psnId = null;
        if (data != null) {
            JsonArray admins = data.getAsJsonArray("administrators");
            if (admins != null && !admins.isEmpty()) {
                JsonObject firstAdmin = admins.get(0).getAsJsonObject();
                if (firstAdmin.has("psnId")) {
                    psnId = firstAdmin.get("psnId").getAsString();
                }
            }
        }
        ExternalAuthRequestDTO requestDTO = new ExternalAuthRequestDTO();
        requestDTO.setOrgId(sysDepart.getEsignOrgId());
        requestDTO.setTransactorPsnId(psnId);
        requestDTO.setLongTermEffective(true);
        requestDTO.setSealIds(Collections.singletonList(sealId));

        ExternalAuthRequestDTO.AuthorizedOrgInfoDTO orgInfo = new ExternalAuthRequestDTO.AuthorizedOrgInfoDTO();
        orgInfo.setOrgName(NAME_MAIN_ORGANIZATION);
        orgInfo.setOrgIdCardNum(MAIN_CARD_NUM);
        requestDTO.setAuthorizedOrgInfo(orgInfo);

        EsignHttpResponse orgSealsExternalAuth = orgSealsExternalAuth(requestDTO);
        JsonObject orgSealsExternalAuthObject = gson.fromJson(orgSealsExternalAuth.getBody(), JsonObject.class);
        System.out.println("请求返回："+orgSealsExternalAuthObject);

        return null;
    }

    @Override
    public String templatePreviewUrl(String docTemplateId) throws EsignDemoException {
        EsignHttpResponse getTemplatePreview = getTemplatePreviewUrl(docTemplateId);
        JsonObject getTemplatePreview1 = gson.fromJson(getTemplatePreview.getBody(), JsonObject.class);

        // 检查 data 对象是否存在
        if (!getTemplatePreview1.has("data") || !getTemplatePreview1.get("data").isJsonObject()) {
            throw new EsignDemoException("响应中缺少 data 字段");
        }

        JsonObject data = getTemplatePreview1.getAsJsonObject("data");

        // 提取 docTemplatePreviewUrl
        if (!data.has("docTemplatePreviewUrl") || !data.get("docTemplatePreviewUrl").isJsonPrimitive()) {
            throw new EsignDemoException("缺少 docTemplatePreviewUrl 字段");
        }

        String previewUrl = data.get("docTemplatePreviewUrl").getAsString();
        System.err.println("查询模板详情返回：" + previewUrl);
        return previewUrl;
    }

    @Override
    public Boolean signCallback(SignCallbackDTO jsonObject) {
        try {
            if(jsonObject.getAction().equals("SIGN_MISSON_COMPLETE")){
                if(jsonObject.getSignResult().equals(2) && jsonObject.getResultDescription().equals("签署完成")){
                    AppContractSign appContractSign = appContractSignMapper.selectOne(Wrappers.<AppContractSign>lambdaQuery()
                            .eq(AppContractSign::getSignFlowId, jsonObject.getSignFlowId()));
                    if(null != appContractSign && familyMembersMapper.selectById(appContractSign.getFamilyId()).getPsnId().equals(jsonObject.getOperator().getPsnId())){
                        appContractSign.setIsSign(1).setSignTime(new Date());
                        return appContractSignMapper.updateById(appContractSign) > 0;
                    }
                }
            }
        } catch (Exception e) {
            log.error( e.getMessage());
            return false;
        }
        return true;
    }

    @Override
    public List<AppContractSign> queryWaitSignList(String orderId) {
        List<AppContractSign> appContractSigns = appContractSignMapper.selectList(Wrappers.<AppContractSign>lambdaQuery().eq(AppContractSign::getOrderId, orderId));
        appContractSigns.forEach(a -> {
            a.setFullName(familyMembersMapper.selectById(a.getFamilyId()).getFullName());
        });
        return appContractSigns;
    }

    @Override
    public IPage<ContractSignVO> queryUserSignContractList(ContractSignDTO contractSignDTO) {
        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        contractSignDTO.setOrgCode(loginUser.getOrgCode());
        Page<ContractSignVO> page = new Page<>(contractSignDTO.getPageNo(), contractSignDTO.getPageSize());
        return appContractSignMapper.queryUserSignContractList(page,contractSignDTO);
    }

    public String orgAuthorizedSeal(String orgId) throws EsignDemoException {
        // 使用传入的 orgId
        EsignHttpResponse orgAuthorizedSealList = orgAuthorizedSealList("585f3eabc65b42b1ad5ae56f4e2bdde6");
        JsonObject orgAuthorizedSealListObject = gson.fromJson(orgAuthorizedSealList.getBody(), JsonObject.class);

        // 检查 data.seals 是否存在
        if (orgAuthorizedSealListObject.has("data") &&
                orgAuthorizedSealListObject.getAsJsonObject("data").has("seals")) {

            JsonArray seals = orgAuthorizedSealListObject.getAsJsonObject("data").getAsJsonArray("seals");

            for (JsonElement sealElement : seals) {
                JsonObject seal = sealElement.getAsJsonObject();
                // 条件判断
                if (orgId.equals(seal.get("authorizerOrgId").getAsString()) &&
                        "PUBLIC".equals(seal.get("sealBizType").getAsString())) {

                    return seal.get("sealId").getAsString(); // 返回匹配的 sealAuthBizId
                }
            }
        }

        return null; // 无匹配项返回 null
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null || !filename.contains(".")) {
            return "";
        }
        return filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
    }
}

