package com.sunxung.factoring.service.financing.contract.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.enums.FinancingCurrentStageEnum;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.entity.customerinformation.ElectronicSignaturePersonal;
import com.sunxung.factoring.entity.entprise.Enterprise;
import com.sunxung.factoring.entity.financing.apply.CFinancingBasicInfo;
import com.sunxung.factoring.entity.financing.contract.*;
import com.sunxung.factoring.entity.financing.review.ReviewQuotaDisburse;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.tradingPlatform.Platform;
import com.sunxung.factoring.mapper.financing.contract.ContractSignConfirmMapper;
import com.sunxung.factoring.service.customerinformation.IElectronicSignaturePersonalService;
import com.sunxung.factoring.service.entprise.IEnterpriseService;
import com.sunxung.factoring.service.financing.apply.ICFinancingBasicInfoService;
import com.sunxung.factoring.service.financing.contract.*;
import com.sunxung.factoring.service.financing.review.ReviewQuotaDisburseService;
import com.sunxung.factoring.service.project.BusinessAssigneeService;
import com.sunxung.factoring.service.project.BusinessProcessingLogService;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import com.sunxung.factoring.service.tradingPlatform.PlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

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

    @Autowired
    private IContractInfoService contractInfoService;
    @Autowired
    private ReviewQuotaDisburseService reviewQuotaDisburseService;
    @Autowired
    private ICFinancingBasicInfoService financingBasicInfoService;
    @Autowired
    private BusinessAssigneeService assigneeService;
    @Autowired
    private FlowableService flowableService;
    @Autowired
    private BusinessProcessingLogService processingLogService;
    @Autowired
    private UserService userService;
    @Autowired
    private IElectronicSignaturePersonalService electronicSignaturePersonalService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private ISysCustomerService sysCustomerService;
    @Autowired
    private PlatformService platformService;
    @Autowired
    private IContractElectronicInfoService contractElectronicInfoService;
    @Autowired
    private IContractElectronicCustomerInfoService contractElectronicCustomerInfoService;

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

        String key = ConstantUtil.FINANCING_APPLY;
        ContractInfo contractInfo = contractInfoService.getById(contractSignConfirm.getContractInfoId());
        if (contractInfo == null) {
            throw new BusinessException(CodeUtil.FAIL, "获取不到对应合同信息");
        }
        ReviewQuotaDisburse quotaDisburse = reviewQuotaDisburseService.getById(contractInfo.getReviewQuotaDisburseId());
        if (quotaDisburse == null) {
            throw new BusinessException(CodeUtil.FAIL, "获取不到对应额度支用信息");
        }
        CFinancingBasicInfo financingBasicInfo = financingBasicInfoService.getById(quotaDisburse.getFinancingBasicInfoId());

        Map<String, Object> procVariables = new HashMap<>(1);
        String legalSpecialistStr = assigneeService.getCandidateByBusiness(financingBasicInfo.getId(), key, ConstantUtil.ASSIGNEE_LEGAL_SPECIALIST);
        procVariables.put(ConstantUtil.CONTRACT_APPROVAL_CANDIDATE, legalSpecialistStr);
        Map<String, Object> msgVariables = new HashMap<>(2);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, financingBasicInfo.getBusinessNumber());
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "业务编号为“" + financingBasicInfo.getBusinessNumber() + "”的项目已inOut“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(key) + "—formBusiness”阶段，");

        BusinessProcessingLog processingLog = processingLogService.getByBusinessTypeBusinessKey(key, financingBasicInfo.getId());
        if (processingLog == null) {
            throw new BusinessException(CodeUtil.FAIL, "获取不到对应的业务处理日志");
        }
        ThreadLocalUtil.setUser(userService.getByLoginName("admin"));
        List<Long> receiverUserIds = userService.findUserIdByRole(ConstantUtil.LEGAL_SPECIALIST);

        String conclusion = ConstantConversionUtil.processApprovalResult.get(contractSignConfirm.getConclusion()).equals("驳回") ?
                "退回" : ConstantConversionUtil.processApprovalResult.get(contractSignConfirm.getConclusion());
        Boolean result = flowableService.completeMyTask(processingLog.getHistoricTaskId(), financingBasicInfo, procVariables,
                conclusion, contractSignConfirm.getId(), msgVariables, key, receiverUserIds);
        if (result == null || !result) {
            throw new ValidatorException(CodeUtil.FAIL, "合同制作提交时出错啦！");
        }
        if (ConstantConversionUtil.APPROVAL_RESULT_PASS.equals(contractInfo.getConclusion())) {
            //修改融资申请当前阶段
            financingBasicInfo.setCurrentStage(FinancingCurrentStageEnum.CONTRACT_APPROVAL.getCode());
            financingBasicInfoService.updateById(financingBasicInfo);
        } else if (ConstantConversionUtil.APPROVAL_RESULT_BACK.equals(contractInfo.getConclusion())) {
            //修改融资申请当前阶段
            financingBasicInfo.setCurrentStage(FinancingCurrentStageEnum.CONTRACT_MAKING.getCode());
            financingBasicInfoService.updateById(financingBasicInfo);
        }
        return contractSignConfirm;
    }

    @Override
    public ContractSignConfirm getView(Long id) {
        ContractSignConfirm contractSignConfirm = getById(id);
        List<ContractElectronicInfo> electronicInfoList = contractElectronicInfoService.list(new QueryWrapper<ContractElectronicInfo>()
                .eq("contract_info_id", contractSignConfirm.getContractInfoId()));
        if (CollectionUtil.isNotEmpty(electronicInfoList)) {
            electronicInfoList.stream().forEach(contractElectronicInfo -> {
                List<ContractElectronicCustomerInfo> customerInfos = contractElectronicCustomerInfoService.list(new QueryWrapper<ContractElectronicCustomerInfo>()
                        .eq("contract_electronic_info_id", contractElectronicInfo.getId()));
                contractElectronicInfo.setContractElectronicCustomerInfos(customerInfos);
            });
            Set<Long> sysCustomerIds = getCustomerIds(electronicInfoList);
            List<ContractElectronicVo> contractElectronicVos = getContractElectronicVoList(electronicInfoList, sysCustomerIds);
            contractSignConfirm.setElectronicInfoList(electronicInfoList);
            contractSignConfirm.setContractElectronicVos(contractElectronicVos);
        }
        return contractSignConfirm;
    }

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

    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 ("1".equals(sysCustomer.getAccountType())) {
                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;
    }
}
