package com.sunxung.factoring.service.salescontractmanagement.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itextpdf.text.pdf.PdfReader;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.component.util.onlineConverter.OfficeConverterUtil;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.dict.impl.ProjectInitiationStatusDict;
import com.sunxung.factoring.dict.impl.SalesContractPersonTypeDict;
import com.sunxung.factoring.entity.customerinformation.ElectronicSignaturePersonal;
import com.sunxung.factoring.entity.electronicsignature.FddSignData;
import com.sunxung.factoring.entity.salescontractmanagement.*;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.entity.sys.FileStorageDO;
import com.sunxung.factoring.entity.sys.User;
import com.sunxung.factoring.mapper.salescontractmanagement.SalesContractSupplementApprovalMapper;
import com.sunxung.factoring.service.customerinformation.IElectronicSignaturePersonalService;
import com.sunxung.factoring.service.project.BusinessAssigneeService;
import com.sunxung.factoring.service.salescontractmanagement.*;
import com.sunxung.factoring.service.sys.FileService;
import com.sunxung.factoring.service.sys.FileStorageService;
import com.sunxung.factoring.service.sys.ISysAttachmentRefService;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.sys.dto.AttachmentDto;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

/**
 * <p>
 * 销售合同-变更审核表 服务实现类
 * </p>
 *
 * @author daxian
 * @since 2022-03-03
 */
@Service("sales_supplement_approvalService")
public class SalesContractSupplementApprovalServiceImpl extends ServiceImpl<SalesContractSupplementApprovalMapper, SalesContractSupplementApproval> implements ISalesContractSupplementApprovalService {

    @Autowired
    private ISysAttachmentRefService sysAttachmentRefService;
    @Autowired
    private ISalesContractSupplementApprovalPersonInfoHistoryRefService salesContractSupplementApprovalPersonInfoHistoryRefService;
    @Autowired
    private SalesContractService salesContractService;
    @Autowired
    private ISalesContractSupplementInfoService salesContractSupplementInfoService;
    @Autowired
    private ICSalesContractSupplementBasicInfoService salesContractSupplementBasicInfoService;
    @Autowired
    private IElectronicSignaturePersonalService electronicSignaturePersonalService;
    @Autowired
    private ICSalesSupplementSignConfirmationService salesSupplementSignConfirmationService;
    @Autowired
    private ICSalesSupplementSignConfirmationElectronicInfoService salesSupplementSignConfirmationElectronicInfoService;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private FlowableService flowableService;
    @Autowired
    private UserService userService;
    @Autowired
    private ISalesContractSupplementApprovalCommentInfoService salesContractSupplementApprovalCommentInfoService;
    @Autowired
    private FileService fileService;
    @Autowired
    private ISalesContractPersonInfoService salesContractPersonInfoService;
    @Autowired
    private ICSalesContractBasicInfoService salesContractBasicInfoService;

    @Override
    public SalesContractSupplementApproval getView(Long id) {

        SalesContractSupplementApproval salesContractSupplementApproval = getById(id);
        if (salesContractSupplementApproval == null) {
            throw new BusinessException(CodeUtil.FAIL, "获取不到对应销售合同变更审批信息");
        }

        AttachmentDto attachmentDto = AttachmentDto.builder()
                .setEntityId(id)
                .setChildEnum(FileModuleDict.ChildEnum.SALES_CONTRACT_SUPPLEMENT_APPROVAL_FILE)
                .build();
        List<FileStorage> files = sysAttachmentRefService.getFiles(attachmentDto);

        List<SalesContractSupplementApprovalPersonInfoHistoryRef> personInfoHistoryRefs = salesContractSupplementApprovalPersonInfoHistoryRefService.lambdaQuery()
                .eq(SalesContractSupplementApprovalPersonInfoHistoryRef::getSalesContractSupplementApprovalId, id).list();
        salesContractSupplementApproval.setFiles(files);
        salesContractSupplementApproval.setPersonInfoHistoryRef(personInfoHistoryRefs);

        return salesContractSupplementApproval;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doApproval(SalesContractSupplementApproval supplementApproval) {

        if (supplementApproval == null || supplementApproval.getBusinessKey() == null) {
            throw new ValidatorException(CodeUtil.FAIL, "审核信息或者业务id不能为空");
        }

        CSalesContract contractManagement = salesContractService.getById(supplementApproval.getBusinessKey());
        if (contractManagement == null) {
            throw new BusinessException(CodeUtil.FAIL, "获取不到对应销售合同管理信息");
        }

        //销售合同变更信息
        CSalesContractSupplementInfo supplementInfo = salesContractSupplementInfoService.getOne(new QueryWrapper<CSalesContractSupplementInfo>()
                .eq("c_sales_contract_management_id", contractManagement.getId())
                .orderByDesc("gmt_create")
                .last("limit 1"));
        if (supplementInfo == null) {
            throw new BusinessException(CodeUtil.FAIL, "获取不到对应变更录入信息");
        }

        supplementApproval.setSalesContractSupplementInfoId(supplementInfo.getId());
        supplementApproval.setAuditorId(ThreadLocalUtil.getUserId());
        save(supplementApproval);


        //电子签信息
        CSalesSupplementSignConfirmation signConfirmation = new CSalesSupplementSignConfirmation();
        List<CSalesSupplementSignConfirmationElectronicInfo> signConfirmationElectronicInfos = new ArrayList<>();
        ElectronicSignaturePersonal signaturePersonal = new ElectronicSignaturePersonal();

        //已通过 且 需要合同签署时 生成签署信息
        if (supplementApproval.getApprovalConclusion().equals(ConstantConversionUtil.APPROVAL_RESULT_PASS) && supplementApproval.getSignConfirm() == 1) {

            //保存文件信息
            AttachmentDto attachmentDto = AttachmentDto.builder()
                    .setEntityId(supplementApproval.getId())
                    .setChildEnum(FileModuleDict.ChildEnum.SALES_CONTRACT_SUPPLEMENT_APPROVAL_FILE)
                    .build();
            List<Long> fileIds = supplementApproval.getFileIds();
            if (CollectionUtil.isNotEmpty(fileIds)) {
                sysAttachmentRefService.saveRef(fileIds, attachmentDto);
            }

            List<SalesContractSupplementApprovalPersonInfoHistoryRef> salesContractPersonInfos = supplementApproval.getPersonInfoHistoryRef();
            SalesContractSupplementApprovalPersonInfoHistoryRef signPerson = salesContractPersonInfos.get(0);
            if (signPerson == null) {
                throw new ValidatorException(CodeUtil.FAIL, "合同签署人必须选择一个！");
            }
            if (StringUtil.isEmpty(signPerson.getName()) || StringUtil.isEmpty(signPerson.getMobile())) {
                throw new ValidatorException(CodeUtil.FAIL, "签署人信息必须全填！");
            }
            ElectronicSignaturePersonal oldElectronicSignaturePersonal = electronicSignaturePersonalService.lambdaQuery()
                    .eq(ElectronicSignaturePersonal::getName, signPerson.getName())
                    .eq(ElectronicSignaturePersonal::getMobile, signPerson.getMobile()).one();
            if (oldElectronicSignaturePersonal != null) {
                signaturePersonal = oldElectronicSignaturePersonal;
            } else {
                ElectronicSignaturePersonal electronicSignaturePersonal = new ElectronicSignaturePersonal();
                BeanUtils.copyProperties(signPerson, electronicSignaturePersonal, "id");
                electronicSignaturePersonal.setAuthStatus(0);
                electronicSignaturePersonalService.save(electronicSignaturePersonal);
                electronicSignaturePersonalService.updateInfo(electronicSignaturePersonal);
                signaturePersonal = electronicSignaturePersonal;
            }
            signPerson.setSalesContractSupplementApprovalId(supplementApproval.getId());
            salesContractSupplementApprovalPersonInfoHistoryRefService.save(signPerson);

            List<FileStorage> files = sysAttachmentRefService.getFiles(attachmentDto);
            if (CollectionUtil.isEmpty(files)) {
                throw new ValidatorException(CodeUtil.FAIL, "签署文件为空");
            }
            signConfirmation.setcSalesContractSupplementInfoId(supplementInfo.getId());
            salesSupplementSignConfirmationService.save(signConfirmation);

            //保存文件信息
            AttachmentDto attachmentDtoSign = AttachmentDto.builder()
                    .setEntityId(signConfirmation.getId())
                    .setChildEnum(FileModuleDict.ChildEnum.SALES_SUPPLEMENT_SIGN_CONFIRM_FILE)
                    .build();

            sysAttachmentRefService.saveRef(fileIds, attachmentDtoSign);

            for (FileStorage fileStorage : files) {
                CSalesSupplementSignConfirmationElectronicInfo supplementSignConfirmationElectronicInfo = new CSalesSupplementSignConfirmationElectronicInfo();

                supplementSignConfirmationElectronicInfo.setcSalesSupplementSignConfirmationId(signConfirmation.getId());
                supplementSignConfirmationElectronicInfo.setContractName(fileStorage.getOriginalName());
                supplementSignConfirmationElectronicInfo.setFileId(fileStorage.getId());
                supplementSignConfirmationElectronicInfo.setElectronicSignaturePersonalId(signaturePersonal.getId());
                supplementSignConfirmationElectronicInfo.setSignStatus(0);
                salesSupplementSignConfirmationElectronicInfoService.save(supplementSignConfirmationElectronicInfo);
                fileStorageService.saveAttachmentRefByFileStorage(fileStorage, FileModuleDict.ChildEnum.SIGN_CONFIRM_FILE,
                        supplementSignConfirmationElectronicInfo.getId());
            }
        }

        handleProcess(contractManagement, supplementApproval);

        if (supplementApproval.getApprovalConclusion().equals(ConstantConversionUtil.APPROVAL_RESULT_PASS) && supplementApproval.getSignConfirm() == 0){
            //审核结论通过且签署确认为是时变更状态为已完成
            contractManagement.setContractStatus(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode());
            salesContractService.updateById(contractManagement);
        }

    }

    @Override
    public SalesContractSupplementApproval approval(Long managementId) {

        SalesContractSupplementApproval approval = new SalesContractSupplementApproval();
        CSalesContract salesContract = salesContractService.getById(managementId);
        CSalesContractBasicInfo contractBasicInfo = salesContractBasicInfoService.lambdaQuery()
                .eq(CSalesContractBasicInfo::getcSalesContractManagementId, managementId).one();
        CSalesContractSupplementInfo lastSupplementInfo = salesContractSupplementInfoService.lambdaQuery()
                .eq(CSalesContractSupplementInfo::getcSalesContractManagementId, managementId)
                .orderByDesc(CSalesContractSupplementInfo::getGmtCreate).last("limit 1").one();
        CSalesContractSupplementBasicInfo supplementBasicInfo = salesContractSupplementBasicInfoService.lambdaQuery()
                .eq(CSalesContractSupplementBasicInfo::getcSalesContractSupplementInfoId, lastSupplementInfo.getId()).one();
        //签署人信息
        List<CSalesContractPersonInfo> personInfos = salesContractPersonInfoService
                .lambdaQuery().eq(CSalesContractPersonInfo::getcSalesContractBasicInfoId, contractBasicInfo.getId()).list();
        List<SalesContractSupplementApprovalPersonInfoHistoryRef> personInfoHistoryRefs = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(personInfos)) {
            for (CSalesContractPersonInfo person : personInfos) {
                if (person.getType().equals(SalesContractPersonTypeDict.ChildEnum.SALESCONTRACTPERSONTYPE_SIGN.getCode())) {
                    SalesContractSupplementApprovalPersonInfoHistoryRef personHis = new SalesContractSupplementApprovalPersonInfoHistoryRef();
                    BeanUtils.copyProperties(person,personHis,"id");
                    personInfoHistoryRefs.add(personHis);
                }
            }
        }
        approval.setPersonInfoHistoryRef(personInfoHistoryRefs);

        List<FileStorageDO> storageDOList = fileService
                .findByBusinessId(supplementBasicInfo.getId(), FileModuleDict.ChildEnum.SALES_CONTRACT_SUPPLEMENT_CONTRACT_FILE.getCode());
        List<FileStorage> fileStorageList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(storageDOList)){
            storageDOList.forEach(fileStorageDO -> {
                FileStorage fileStorage = new FileStorage();
                BeanUtils.copyProperties(fileStorageDO,fileStorage,"id");
                fileStorage.setFileType(fileStorageDO.getType());
                fileStorage.setAbsolutePath(fileStorageDO.getAbsolutePath());
                fileStorage.setOriginalName(fileStorageDO.getOriginalName());
                fileStorage.setName(fileStorageDO.getOriginalName());
                fileStorage.setPath(fileStorageDO.getPath());
                fileStorageService.add(fileStorage);
                fileStorageList.add(fileStorage);
            });
        }
        approval.setFiles(fileStorageList);

        return approval;
    }

    private void handleProcess(CSalesContract contractManagement, SalesContractSupplementApproval supplementApproval) {
        //流程处理
        String processKey = ConstantUtil.SALES_CONTRACT_CHANGE_PROCESS;
        String assigneeKey = ConstantUtil.SUPPLEMENT_SIGN_CONFIRMATION + ConstantUtil.ASSIGNEE;

        Map<String, Object> procVariables = new HashMap<>(1);
        User admin = userService.getByLoginName("admin");
        procVariables.put(assigneeKey, admin.getId());
        String result;
        if (supplementApproval.getApprovalConclusion().equals(ConstantConversionUtil.APPROVAL_RESULT_BACK)) {
            result = ConstantConversionUtil.APPROVAL_RESULT_BACK_DISPLAY;
        } else {
            if (supplementApproval.getSignConfirm() == 1) {
                result = ConstantConversionUtil.APPROVAL_RESULT_SIGN_DISPLAY;
            } else {
                result = ConstantConversionUtil.APPROVAL_RESULT_NO_SIGN_DISPLAY;
            }
        }
        Map<String, Object> msgVariables = new HashMap<>(2);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, contractManagement.getBusinessNumber());
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "业务编号为" + contractManagement.getBusinessNumber() + "”的项目已inOut“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(processKey) + "—formBusiness”阶段，");
        Boolean success = flowableService.completeMyTask(supplementApproval.getTaskId(), contractManagement, procVariables,
                result,
                supplementApproval.getId(), msgVariables, processKey);
        if (success == null || !success) {
            throw new ValidatorException(CodeUtil.FAIL, "销售合同审批出错啦！");
        }

    }


}
