package com.inkasso.factoring.financingmanagement.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.inkasso.adapter.exception.BusinessException;
import com.inkasso.adapter.util.CodeUtil;
import com.inkasso.adapter.web.LoginUserHolder;
import com.inkasso.factoring.common.entity.ResponseJson;
import com.inkasso.factoring.common.util.DateUtil;
import com.inkasso.factoring.common.util.ElectronicSignatureUtil;
import com.inkasso.factoring.creditmanagement.entity.Enterprise;
import com.inkasso.factoring.creditmanagement.service.IEnterpriseService;
import com.inkasso.factoring.electronicSignature.entity.ElectronicSignaturePersonal;
import com.inkasso.factoring.electronicSignature.entity.FddSignData;
import com.inkasso.factoring.electronicSignature.service.IElectronicSignaturePersonalService;
import com.inkasso.factoring.financingmanagement.dao.ContractSignConfirmMapper;
import com.inkasso.factoring.financingmanagement.entity.ContractElectronicCustomerInfo;
import com.inkasso.factoring.financingmanagement.entity.ContractElectronicInfo;
import com.inkasso.factoring.financingmanagement.entity.ContractSignConfirm;
import com.inkasso.factoring.financingmanagement.entity.SysCustomer;
import com.inkasso.factoring.financingmanagement.entity.vo.ContractElectronicVo;
import com.inkasso.factoring.financingmanagement.service.IContractElectronicCustomerInfoService;
import com.inkasso.factoring.financingmanagement.service.IContractElectronicInfoService;
import com.inkasso.factoring.financingmanagement.service.IContractSignConfirmService;
import com.inkasso.factoring.financingmanagement.service.ISysCustomerService;
import com.inkasso.factoring.tradingPlatform.entity.Platform;
import com.inkasso.factoring.tradingPlatform.service.ITradingPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * @Description :
 * @Author : L.Jia
 * @Date: 2024-02-23 14:19
 */
@Service
public class ContractSignConfirmServiceImpl extends ServiceImpl<ContractSignConfirmMapper, ContractSignConfirm>
        implements IContractSignConfirmService {

    @Autowired
    private ISysCustomerService sysCustomerService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private ITradingPlatformService platformService;
    @Autowired
    private IContractElectronicCustomerInfoService contractElectronicCustomerInfoService;
    @Autowired
    private IContractElectronicInfoService contractElectronicInfoService;
    //    @Autowired
//    private IElectronicPersonInfoService electronicPersonInfoService;
    @Autowired
    private IElectronicSignaturePersonalService electronicSignaturePersonalService;
    @Autowired
    private RestTemplate restTemplate;
    @Value("${trade.contractSignConfirmSubmitUrl}")
    private String contractSignConfirmSubmitUrl;

    @Override
    public ContractSignConfirm getSignConfirmDetail(Long id) {

        ContractSignConfirm contractSignConfirm = baseMapper.getByFinancingApplyId(id, false);
        Long contractInfoId = baseMapper.getContractInfoIdByFinancingApplyId(id);
        if (null == contractSignConfirm) {
            contractSignConfirm = new ContractSignConfirm();
            contractSignConfirm.setContractInfoId(contractInfoId);
        }
        List<ContractElectronicInfo> electronicInfoList = contractElectronicInfoService.list(new QueryWrapper<ContractElectronicInfo>()
                .eq("contract_info_id", contractInfoId));
        if (CollectionUtil.isNotEmpty(electronicInfoList)) {
            Set<Long> sysCustomerIds = getCustomerIds(electronicInfoList);
            //生成签署链接
            doSign(electronicInfoList, sysCustomerIds);
            List<ContractElectronicVo> contractElectronicVos = getContractElectronicVoList(electronicInfoList, sysCustomerIds);
            contractSignConfirm.setElectronicInfoList(electronicInfoList);
            contractSignConfirm.setContractElectronicVos(contractElectronicVos);
        }
        return contractSignConfirm;
    }

    private List<ContractElectronicVo> getContractElectronicVoList(List<ContractElectronicInfo> electronicInfoList, Set<Long> sysCustomerIds) {
        List<ContractElectronicVo> contractElectronicVos = new ArrayList<>();
        for (Long customerId : sysCustomerIds) {
            List<ContractElectronicCustomerInfo> contractElectronicCustomerInfos = new ArrayList<>();
            for (ContractElectronicInfo contractElectronicInfo : electronicInfoList) {
                for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : contractElectronicInfo.getContractElectronicCustomerInfos()) {
                    if (customerId.equals(contractElectronicCustomerInfo.getSysCustomerId())) {
                        contractElectronicCustomerInfos.add(contractElectronicCustomerInfo);
                    }
                }
            }
            ContractElectronicVo contractElectronicVo = new ContractElectronicVo();
            contractElectronicVo.setContractLink(contractElectronicCustomerInfos.get(0).getShortContractLink());
            SysCustomer sysCustomer = sysCustomerService.getById(contractElectronicCustomerInfos.get(0).getSysCustomerId());
            if (sysCustomer.getAccountType().equals("1")) {
//                ElectronicPersonInfo electronicPersonInfo = electronicPersonInfoService.getById(sysCustomer.getEntBusinessId());
                ElectronicSignaturePersonal electronicSignaturePersonal = electronicSignaturePersonalService.getById(sysCustomer.getEntBusinessId());
                contractElectronicVo.setName(electronicSignaturePersonal.getName());
                contractElectronicVo.setType(3);
                contractElectronicVo.setAuthStatus(electronicSignaturePersonal.getAuthStatus() == 1 ? true : false);
                contractElectronicVo.setAuthUrl(electronicSignaturePersonal.getShortAuthUrl());
                contractElectronicVo.setSysCustomerId(sysCustomer.getId());
            } else {
                if (sysCustomer.getEntBusinessId() != null) {
                    Enterprise enterprise = enterpriseService.getById(sysCustomer.getEntBusinessId());
                    contractElectronicVo.setName(enterprise.getCorporateName());
                    contractElectronicVo.setType(1);
                    contractElectronicVo.setAuthStatus(enterprise.getAuthStatus());
                    contractElectronicVo.setAuthUrl(enterprise.getShortAuthUrl());
                    contractElectronicVo.setSysCustomerId(sysCustomer.getId());
                } else if (sysCustomer.getPlatformId() != null) {
                    Platform platform = platformService.getById(sysCustomer.getPlatformId());
                    contractElectronicVo.setName(platform.getPlatformName());
                    contractElectronicVo.setType(2);
                    contractElectronicVo.setAuthStatus(platform.getAuthStatus() == 1 ? true : false);
                    contractElectronicVo.setAuthUrl(platform.getShortAuthUrl());
                    contractElectronicVo.setSysCustomerId(sysCustomer.getId());
                }
            }
            contractElectronicVo.setContractElectronicCustomerInfos(contractElectronicCustomerInfos);
            contractElectronicVos.add(contractElectronicVo);
        }
        return contractElectronicVos;
    }

    private Set<Long> getCustomerIds(List<ContractElectronicInfo> electronicInfoList) {
        Set<Long> sysCustomerIds = new HashSet();
        for (ContractElectronicInfo contractElectronicInfo : electronicInfoList) {
            List<ContractElectronicCustomerInfo> contractElectronicCustomerInfos = contractElectronicCustomerInfoService.list(new QueryWrapper<ContractElectronicCustomerInfo>().eq("contract_electronic_info_id", contractElectronicInfo.getId()));
            for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : contractElectronicCustomerInfos) {
                sysCustomerIds.add(contractElectronicCustomerInfo.getSysCustomerId());
            }
        }
        return sysCustomerIds;
    }

    /**
     * 生成签署链接
     *
     * @param electronicInfoList
     */
    private void doSign(List<ContractElectronicInfo> electronicInfoList, Set<Long> sysCustomerIds) {
        //同一签署人需要签署的文件
        if (CollectionUtil.isNotEmpty(sysCustomerIds)) {
            for (Long sysCustomerId : sysCustomerIds) {
                List<ContractElectronicCustomerInfo> list = new ArrayList<>();
                for (ContractElectronicInfo contractElectronicInfo : electronicInfoList) {
                    List<ContractElectronicCustomerInfo> contractElectronicCustomerInfos = contractElectronicCustomerInfoService.list(new QueryWrapper<ContractElectronicCustomerInfo>().eq("contract_electronic_info_id", contractElectronicInfo.getId()));
                    for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : contractElectronicCustomerInfos) {
                        if (sysCustomerId.equals(contractElectronicCustomerInfo.getSysCustomerId())) {
                            list.add(contractElectronicCustomerInfo);
                        }
                    }
                }
                SysCustomer sysCustomer = sysCustomerService.getById(sysCustomerId);
                ElectronicSignaturePersonal electronicSignaturePersonal;
                Enterprise enterpriseBusinessInfo;
                //  Integer autoSignStatus = sysCustomer.getAutoSignStatus() == null ? 0 : sysCustomer.getAutoSignStatus();
                Integer autoSignStatus = 0;
                if ("2".equals(sysCustomer.getAccountType())) {
                    //公司
                    if (sysCustomer.getEntBusinessId() != null) {
                        Enterprise enterprise = enterpriseService.getById(sysCustomer.getEntBusinessId());
                        autoSignStatus = enterprise.getAutoSignStatus();
                    } else if (sysCustomer.getPlatformId() != null) {
                        Platform platform = platformService.getById(sysCustomer.getPlatformId());
                        autoSignStatus = platform.isAutoSignStatus() ? 1 : 0;
                    }
                }
                if (autoSignStatus == 0) {
                    //批量生成手动签署的链接
                    List<FddSignData> fddSignDataList = new ArrayList<>();
                    if (sysCustomer.getAuthStatus()) {
                        for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : list) {
                            FddSignData fddSignData = new FddSignData();
                            ContractElectronicInfo contractElectronicInfo = contractElectronicInfoService.getById(contractElectronicCustomerInfo.getContractElectronicInfoId());
                            if (contractElectronicCustomerInfo.getContractLink() == null || contractElectronicCustomerInfo.getContractLink().equals("")) {
                                fddSignData.setContractId(contractElectronicInfo.getContractId());
                                fddSignData.setContractType("CONTRACT");
                                fddSignData.setSignKeyword(contractElectronicCustomerInfo.getKeyword());
                                String transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
                                fddSignData.setTransactionId(transactionId);
                                fddSignDataList.add(fddSignData);
                                contractElectronicCustomerInfo.setTransactionId(transactionId);
                            }
                        }
                        if (fddSignDataList.size() > 0) {
                            String contractLink = null;
                            if (sysCustomer.getAccountType().equals("1")) {
                                electronicSignaturePersonal = electronicSignaturePersonalService.getById(sysCustomer.getEntBusinessId());
                                contractLink = ElectronicSignatureUtil.manualBatchSign(sysCustomer.getFddCustomerId(), fddSignDataList, electronicSignaturePersonal.getName() + DateUtil.getCurrentDate());
                            } else {
                                if (sysCustomer.getEntBusinessId() != null) {
                                    enterpriseBusinessInfo = enterpriseService.getById(sysCustomer.getEntBusinessId());
                                    contractLink = ElectronicSignatureUtil.manualBatchSign(sysCustomer.getFddCustomerId(), fddSignDataList, enterpriseBusinessInfo.getCorporateName() + DateUtil.getCurrentDate());
                                } else if (sysCustomer.getPlatformId() != null) {
                                    Platform platform = platformService.getById(sysCustomer.getPlatformId());
                                    contractLink = ElectronicSignatureUtil.manualBatchSign(sysCustomer.getFddCustomerId(), fddSignDataList, platform.getPlatformName() + DateUtil.getCurrentDate());
                                }
                            }
                            String shortUrl = ElectronicSignatureUtil.shortUrl(null, contractLink);
                            for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : list) {
                                ContractElectronicInfo contractElectronicInfo = contractElectronicInfoService.getById(contractElectronicCustomerInfo.getContractElectronicInfoId());
                                contractElectronicCustomerInfo.setSysCustomerId(sysCustomer.getId());
                                contractElectronicCustomerInfo.setShortContractLink(shortUrl);
                                contractElectronicCustomerInfo.setShortContractLinkCreate(new Date());
                                contractElectronicCustomerInfo.setContractElectronicInfoId(contractElectronicInfo.getId());
                                contractElectronicCustomerInfo.setSignStatus(false);
                                contractElectronicCustomerInfo.setContractLink(contractLink);
                                contractElectronicCustomerInfoService.updateById(contractElectronicCustomerInfo);
                            }
                        }

                    } else {
                        for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : list) {
                            contractElectronicCustomerInfo.setShortContractLink("认证后点击刷新显示签署链接！");
                            contractElectronicCustomerInfoService.updateById(contractElectronicCustomerInfo);
                        }
                    }
                } else {
                    for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : list) {
                        String transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
                        ContractElectronicInfo contractElectronicInfo = contractElectronicInfoService.getById(contractElectronicCustomerInfo.getContractElectronicInfoId());
                        String docTitle = null;
                        if (contractElectronicCustomerInfo.getSignStatus() == null || !contractElectronicCustomerInfo.getSignStatus()) {
                            if (sysCustomer.getAccountType().equals("1")) {
                                electronicSignaturePersonal = electronicSignaturePersonalService.getById(sysCustomer.getEntBusinessId());
                                docTitle = electronicSignaturePersonal.getName() + DateUtil.getCurrentDate();
                            } else {
                                if (sysCustomer.getEntBusinessId() != null) {
                                    enterpriseBusinessInfo = enterpriseService.getById(sysCustomer.getEntBusinessId());
                                    docTitle = enterpriseBusinessInfo.getCorporateName() + DateUtil.getCurrentDate();
                                } else if (sysCustomer.getPlatformId() != null) {
                                    Platform platform = platformService.getById(sysCustomer.getPlatformId());
                                    docTitle = platform.getPlatformName() + DateUtil.getCurrentDate();
                                }
                            }
                            ElectronicSignatureUtil.autoSign(transactionId, contractElectronicInfo.getContractId(), sysCustomer.getFddCustomerId(), docTitle, contractElectronicCustomerInfo.getKeyword());
                        }
                        contractElectronicCustomerInfo.setSysCustomerId(sysCustomer.getId());
                        contractElectronicCustomerInfo.setShortContractLink("自动签署不需要签署链接");
                        contractElectronicCustomerInfo.setContractElectronicInfoId(contractElectronicInfo.getId());
                        contractElectronicCustomerInfo.setSignStatus(true);
                        contractElectronicCustomerInfo.setContractLink("自动签署不需要签署链接");
                        contractElectronicCustomerInfo.setTransactionId(transactionId);
                        contractElectronicCustomerInfoService.updateById(contractElectronicCustomerInfo);
                    }
                }
            }
        }

        for (ContractElectronicInfo contractElectronicInfo : electronicInfoList) {
            List<ContractElectronicCustomerInfo> contractElectronicCustomerInfos = contractElectronicCustomerInfoService.list(new QueryWrapper<ContractElectronicCustomerInfo>().eq("contract_electronic_info_id", contractElectronicInfo.getId()));
            for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : contractElectronicCustomerInfos) {
                String[] split = contractElectronicInfo.getContractName().split("_");
                String contractName = split[0];
                SysCustomer sysCustomer = sysCustomerService.getById(contractElectronicCustomerInfo.getSysCustomerId());
                if (sysCustomer.getAccountType().equals("1")) {
                    ElectronicSignaturePersonal electronicSignaturePersonal = electronicSignaturePersonalService.getById(sysCustomer.getEntBusinessId());
                    contractElectronicCustomerInfo.setCustomerName(contractName);
                    contractElectronicCustomerInfo.setElectronicSignaturePersonal(electronicSignaturePersonal);
                } else {
                    Enterprise enterprise = enterpriseService.getById(sysCustomer.getEntBusinessId());
                    contractElectronicCustomerInfo.setCustomerName(contractName);
                    contractElectronicCustomerInfo.setEnterprise(enterprise);
                }
                contractElectronicCustomerInfo.setSysCustomer(sysCustomer);
                contractElectronicCustomerInfoService.updateById(contractElectronicCustomerInfo);
            }
            contractElectronicInfo.setContractElectronicCustomerInfos(contractElectronicCustomerInfos);
        }
    }

    @Override
    public SysCustomer findAuthInfo(String sysCustomerId) {
        String customId;
        Boolean authStatus;
        String type;
        String authStatusStr = null;
        SysCustomer sysCustomer = sysCustomerService.getById(sysCustomerId);
        if (sysCustomer.getAccountType().equals("2")) {
            //公司
            if (!sysCustomer.getAuthStatus()) {
                type = sysCustomer.getAccountType();
                customId = String.valueOf(sysCustomer.getFddCustomerId());
                if (sysCustomer.getEntBusinessId() != null) {
                    Enterprise enterprise = enterpriseService.getById(sysCustomer.getEntBusinessId());
                    authStatusStr = ElectronicSignatureUtil.getAuthInfo(enterprise.getSocialCreditCode(), type);
                    enterprise.setAuthStatus(true);
                    enterpriseService.updateById(enterprise);
                } else if (sysCustomer.getPlatformId() != null) {
                    Platform platform = platformService.getById(sysCustomer.getPlatformId());
                    authStatusStr = ElectronicSignatureUtil.getAuthInfo(platform.getSocialCreditCode(), type);
                }
                if (authStatusStr.equals("1")) {
                    authStatus = true;
                    sysCustomer.setAuthStatus(authStatus);
                    sysCustomerService.doAuthBack(customId);
                    if (sysCustomer.getEntBusinessId() != null) {
                        Enterprise enterprise = enterpriseService.getById(sysCustomer.getEntBusinessId());
                        enterprise.setAuthStatus(true);
                        enterpriseService.updateById(enterprise);
                    } else if (sysCustomer.getPlatformId() != null) {
                        Platform platform = platformService.getById(sysCustomer.getPlatformId());
                        platform.setAuthStatus(1);
                        platformService.updateById(platform);
                    }
                } else {
                    authStatus = false;
                }
                sysCustomer.setAuthStatus(authStatus);
            }
        } else if (sysCustomer.getAccountType().equals("1")) {
            //个人
            if (!sysCustomer.getAuthStatus()) {
                type = sysCustomer.getAccountType();
                customId = String.valueOf(sysCustomer.getFddCustomerId());
                authStatusStr = ElectronicSignatureUtil.getAuthInfo(customId, type);
                if (authStatusStr.equals("1")) {
                    authStatus = true;
                    sysCustomer.setAuthStatus(authStatus);
                    sysCustomerService.doAuthBack(customId);
                } else {
                    authStatus = false;
                }
                sysCustomer.setAuthStatus(authStatus);
            }
        }
        sysCustomerService.updateById(sysCustomer);
        return sysCustomer;
    }

    @Override
    public ContractElectronicCustomerInfo findSignInfo(String electronicCustomerInfoId) {
        String customerId;
        String contractId;
        String transtationId;
        ContractElectronicCustomerInfo contractElectronicCustomerInfo = contractElectronicCustomerInfoService.getById(electronicCustomerInfoId);
        if (!contractElectronicCustomerInfo.getSignStatus()) {
            transtationId = contractElectronicCustomerInfo.getTransactionId();
            Long contractElectronicInfoId = contractElectronicCustomerInfo.getContractElectronicInfoId();
            SysCustomer sysCustomer = sysCustomerService.getById(contractElectronicCustomerInfo.getSysCustomerId());
            customerId = sysCustomer.getFddCustomerId();
            ContractElectronicInfo electronicInfo = contractElectronicInfoService.getById(contractElectronicInfoId);
            contractId = electronicInfo.getContractId();
            String signResult = ElectronicSignatureUtil.getSignInfo(customerId, contractId, transtationId);
            if (signResult.equals("3000")) {
                contractElectronicCustomerInfo.setSignStatus(true);
                sysCustomerService.doSignBack(contractId, transtationId);
            } else {
                contractElectronicCustomerInfo.setSignStatus(false);
            }
        }
        return contractElectronicCustomerInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ContractSignConfirm editContractSignConfirm(ContractSignConfirm contractSignConfirm) {

        contractSignConfirm.setAssigneeId(LoginUserHolder.get().getId());
        saveOrUpdate(contractSignConfirm);
        if (contractSignConfirm.getVisible()) {
            List<ContractElectronicInfo> electronicInfoList = contractElectronicInfoService.list(new QueryWrapper<ContractElectronicInfo>()
                    .eq("contract_info_id", contractSignConfirm.getContractInfoId()));
            if (contractSignConfirm.getConclusion().equals("pass")) {
                if (electronicInfoList != null && electronicInfoList.size() > 0) {
                    for (ContractElectronicInfo contractElectronicInfo : electronicInfoList) {
                        List<ContractElectronicCustomerInfo> contractElectronicCustomerInfos = contractElectronicCustomerInfoService.list(new QueryWrapper<ContractElectronicCustomerInfo>()
                                .eq("contract_electronic_info_id", contractElectronicInfo.getId()));
                        for (ContractElectronicCustomerInfo contractElectronicCustomerInfo : contractElectronicCustomerInfos) {
                            if (!contractElectronicCustomerInfo.getSignStatus()) {
                                throw new BusinessException(CodeUtil.FAIL, "所有合同必须都签署完成才能提交！");
                            }
                        }
                    }
                }
            }

            ResponseEntity<String> responseEntity = restTemplate.postForEntity(contractSignConfirmSubmitUrl, contractSignConfirm, String.class);
            ResponseJson responseJson = JSONUtil.toBean(responseEntity.getBody(), ResponseJson.class);
            if (responseEntity.getStatusCode().value() != HttpStatus.OK.value() || !responseJson.isSuccess()) {
                throw new BusinessException(CodeUtil.FAIL, "合同签署提交到B端失败：" + responseJson.getMsg());
            }
        }
        return contractSignConfirm;
    }
}
