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

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.CodeUtil;
import com.sunxung.factoring.component.util.ConstantUtil;
import com.sunxung.factoring.component.util.FlowableUtil;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.dict.impl.ProjectInitiationStatusDict;
import com.sunxung.factoring.entity.businessmanagement.BusinessBasicInfo;
import com.sunxung.factoring.entity.customerinformation.Customer;
import com.sunxung.factoring.entity.customerinformation.ElectronicSignaturePersonal;
import com.sunxung.factoring.entity.project.BusinessAssignee;
import com.sunxung.factoring.entity.project.vo.BusinessProcessingTaskVo;
import com.sunxung.factoring.entity.project.vo.SearchBusinessProcessingTask;
import com.sunxung.factoring.entity.signconfirmation.SignConfirmation;
import com.sunxung.factoring.entity.signconfirmation.SignConfirmationApproval;
import com.sunxung.factoring.entity.signconfirmation.SignConfirmationElectronicInfo;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.mapper.signconfirmation.SignConfirmationMapper;
import com.sunxung.factoring.service.businessmanagement.BusinessBasicInfoService;
import com.sunxung.factoring.service.customerinformation.CustomerService;
import com.sunxung.factoring.service.project.BusinessAssigneeService;
import com.sunxung.factoring.service.signconfirmation.ISignConfirmationApprovalService;
import com.sunxung.factoring.service.signconfirmation.ISignConfirmationElectronicInfoService;
import com.sunxung.factoring.service.signconfirmation.ISignConfirmationService;
import com.sunxung.factoring.service.sys.DictionaryService;
import com.sunxung.factoring.service.sys.FileStorageService;
import com.sunxung.factoring.service.sys.UserService;
import com.sunxung.factoring.service.sys.flowable.FlowableService;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * --销售合同审核人员信息历史表 服务实现类
 * </p>
 *
 * @author liutao
 * @since 2023-05-16
 */
@Service("signConfirmationService")
public class SignConfirmationServiceImpl extends ServiceImpl<SignConfirmationMapper, SignConfirmation> implements ISignConfirmationService {

    @Autowired
    private DictionaryService dictionaryService;

    @Autowired
    private ISignConfirmationService signConfirmationService;

    @Autowired
    private ISignConfirmationElectronicInfoService signConfirmationElectronicInfoService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private FlowableService flowableService;

    @Autowired
    private BusinessAssigneeService assigneeService;

    @Autowired
    private UserService userService;

    @Autowired
    private BusinessBasicInfoService businessBasicInfoService;

    @Autowired
    private ISignConfirmationApprovalService signConfirmationApprovalService;

    @Autowired
    private FileStorageService fileStorageService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startProcess(String moduleName, ElectronicSignaturePersonal electronicSignaturePersonal, List<FileStorage> files, BusinessBasicInfo businessBasicInfo, Long id) {
        SignConfirmation signConfirmation = new SignConfirmation(businessBasicInfo.getBusinessNumber(),
                businessBasicInfo.getName(),
                businessBasicInfo.getEnterpriseCustomerInfoId(),
                moduleName,
                dictionaryService.getByCode(ProjectInitiationStatusDict.ChildEnum.PROCESSING.getCode()).getId());
        signConfirmation.setApprovalId(id);
        signConfirmationService.save(signConfirmation);

        files.forEach(fileStorage -> {
            SignConfirmationElectronicInfo signConfirmationElectronicInfo = new SignConfirmationElectronicInfo();

            signConfirmationElectronicInfo.setSignConfirmationId(signConfirmation.getId());
            signConfirmationElectronicInfo.setContractName(fileStorage.getOriginalName());
            signConfirmationElectronicInfo.setFileId(fileStorage.getId());
            signConfirmationElectronicInfo.setElectronicSignaturePersonalId(electronicSignaturePersonal.getId());
            signConfirmationElectronicInfo.setSignStatus(0);
            signConfirmationElectronicInfoService.save(signConfirmationElectronicInfo);
            fileStorageService.saveAttachmentRefByFileStorage(fileStorage, FileModuleDict.ChildEnum.SIGN_CONFIRM_FILE, signConfirmationElectronicInfo.getId());
        });

        BusinessAssignee projectManager = new BusinessAssignee(signConfirmation.getId(), ConstantUtil.SIGN_CONFIRMATION);
        projectManager.setAssigneeId(businessBasicInfo.getManagerId());
        projectManager.setAssigneeType(ConstantUtil.ASSIGNEE_PROJECT_MANAGER);
        assigneeService.add(projectManager);
        //开启流程
        Map<String, Object> procVariables = new HashMap<>(1);
        procVariables.put(ConstantUtil.SIGN_CONFIRM_ADD + ConstantUtil.ASSIGNEE, businessBasicInfo.getManagerId());
        Map<String, Object> msgVariables = new HashMap<>(2);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "签署确认信息");
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "业务编号为“" + businessBasicInfo.getBusinessNumber() + "”——业务名称为“" + businessBasicInfo.getName() + "”——一笔签署确认管理的项目已进入“"
                        + "签署确认—formBusiness”阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        Customer customer = customerService.getById(businessBasicInfo.getEnterpriseCustomerInfoId());
        // 请输入业务编号、核心企业名称、业务名称
        String queryBusiness = businessBasicInfo.getBusinessNumber() + FlowableUtil.splitChar + customer.getEnterpriseName() + FlowableUtil.splitChar + businessBasicInfo.getBusinessName();
        ProcessInstance processInst = flowableService.startProcessInstance(signConfirmation, procVariables,
                FlowableUtil.generateBusinessKey(signConfirmation, ConstantUtil.SIGN_CONFIRMATION, queryBusiness), null, ConstantUtil.SIGN_CONFIRMATION);
        if (processInst == null) {
            throw new BusinessException(CodeUtil.FAIL, "流程启动失败");
        }
    }

    @Override
    public SignConfirmation get(Long id) {
        return baseMapper.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirm(SignConfirmation signConfirmation) {
        String taskId = signConfirmation.getTaskId();
        SignConfirmation old = getById(signConfirmation.getId());
        old.setRemark(signConfirmation.getRemark());
        old.setSignConclusion(signConfirmation.getSignConclusion());
        updateById(old);
        List<SignConfirmationElectronicInfo> signConfirmationElectronicInfos = signConfirmationElectronicInfoService.lambdaQuery().eq(SignConfirmationElectronicInfo::getSignConfirmationId, signConfirmation.getId()).list();
        boolean anyMatch = signConfirmationElectronicInfos.stream().anyMatch(r -> r.getSignStatus().equals(0));
        if(anyMatch){
            throw new ValidatorException(CodeUtil.FAIL,"合同尚未签署完成，无法提交！");
        }

        List<Long> legalSpecialists = userService.findUserIdByRole(ConstantUtil.LEGAL_SPECIALIST);
        if (legalSpecialists == null || legalSpecialists.size() == 0) {
            throw new ValidatorException(CodeUtil.FAIL, ConstantUtil.OPERATION_SPECIALIST + "角色内无任何用户！");
        }

        BusinessAssignee legalSpecialist = new BusinessAssignee(signConfirmation.getId(), ConstantUtil.SIGN_CONFIRMATION);
        legalSpecialist.setCandidateId(StringUtils.join(legalSpecialists, ","));
        legalSpecialist.setAssigneeType(ConstantUtil.ASSIGNEE_LEGAL_SPECIALIST);
        assigneeService.add(legalSpecialist);

        BusinessBasicInfo businessBasicInfo = businessBasicInfoService.getByBusinessNumber(old.getBusinessNumber());

        Map<String, Object> procVariables = new HashMap<>(1);
        procVariables.put(ConstantUtil.LEGAL_APPROVAL + ConstantUtil._CANDIDATE, legalSpecialist.getCandidateId());
        Map<String, Object> msgVariables = new HashMap<>(2);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "签署确认信息");
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "业务编号为“" + businessBasicInfo.getBusinessNumber() + "”——业务名称为“" + businessBasicInfo.getName() + "”——一笔签署确认管理的项目已进入“"
                        + "法务审核—formBusiness”阶段，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        flowableService.completeMyTask(taskId, signConfirmation, procVariables, null, signConfirmation.getId(), msgVariables, ConstantUtil.SIGN_CONFIRMATION, legalSpecialists);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approval(SignConfirmationApproval signConfirmationApproval) {
        String taskId = signConfirmationApproval.getTaskId();
        SignConfirmation signConfirmation = getById(signConfirmationApproval.getBusinessKey());
        signConfirmationApproval.setSignConfirmationId(signConfirmationApproval.getBusinessKey());
        signConfirmationApprovalService.save(signConfirmationApproval);
        signConfirmation.setStatusId(dictionaryService.getByCode(ProjectInitiationStatusDict.ChildEnum.COMPLETED.getCode()).getId());
        updateById(signConfirmation);
        BusinessBasicInfo businessBasicInfo = businessBasicInfoService.getByBusinessNumber(signConfirmation.getBusinessNumber());

        Map<String, Object> msgVariables = new HashMap<>(2);
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, "签署确认信息");
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "业务编号为“" + businessBasicInfo.getBusinessNumber() + "”——业务名称为“" + businessBasicInfo.getName() + "”——一笔签署确认管理的项目已“"
                        + "完成”，"
                        + ConstantUtil.FLOWABLE_MSG_ASSIGNEE);
        flowableService.completeMyTask(taskId, signConfirmation, null, null, signConfirmationApproval.getId(), msgVariables, ConstantUtil.SIGN_CONFIRMATION);
    }

    @Override
    public List<BusinessProcessingTaskVo> findMyCompletedList(SearchBusinessProcessingTask search) {
        return baseMapper.findMyCompletedList(search);
    }

    @Override
    public List<BusinessProcessingTaskVo> findAllList(SearchBusinessProcessingTask search) {
        return baseMapper.findAllList(search);
    }

    @Override
    public void downloadAllFile(HttpServletResponse response, Long id) {
        List<SignConfirmationElectronicInfo> list = signConfirmationElectronicInfoService.lambdaQuery().eq(SignConfirmationElectronicInfo::getSignConfirmationId, id).list();
        List<FileStorage> fileStorageList = list.stream().map(r -> {
            FileStorage old = fileStorageService.get(r.getFileId());
            FileStorage fileStorage = fileStorageService.get(r.getBackFileId());
            fileStorage.setOriginalName(old.getOriginalName());
            return fileStorage;
        }).collect(Collectors.toList());

        fileStorageService.renameFileStorageList(fileStorageList);
        //文件打包下载
        fileStorageService.downloadZipFile(fileStorageList, "签署确认文件", FileModuleDict.ChildEnum.SIGN_CONFIRM_BACK_ZIP_FILE, response);
    }

    @Override
    public void downloadReportFileZip(HttpServletResponse response, Long id) {
        List<SignConfirmationElectronicInfo> list = signConfirmationElectronicInfoService.lambdaQuery().eq(SignConfirmationElectronicInfo::getSignConfirmationId, id).list();
        List<FileStorage> fileStorageList = list.stream().map(r -> fileStorageService.get(r.getReportFileId())).collect(Collectors.toList());

        fileStorageService.renameFileStorageList(fileStorageList);
        //文件打包下载
        fileStorageService.downloadZipFile(fileStorageList, "签署确认出证文件", FileModuleDict.ChildEnum.SIGN_CONFIRM_BACK_ZIP_FILE, response);
    }
}
