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

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.entity.customerinformation.ElectronicSignaturePersonal;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.project.ProjectInformation;
import com.sunxung.factoring.entity.salescontractmanagement.CSalesContract;
import com.sunxung.factoring.entity.salescontractmanagement.CSalesSignConfirmation;
import com.sunxung.factoring.entity.salescontractmanagement.CSalesSignConfirmationElectronicInfo;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.entity.sys.SysAttachmentRef;
import com.sunxung.factoring.mapper.salescontractmanagement.CSalesSignConfirmationMapper;
import com.sunxung.factoring.service.customerinformation.IElectronicSignaturePersonalService;
import com.sunxung.factoring.service.project.BusinessProcessingLogService;
import com.sunxung.factoring.service.project.IProjectInformationService;
import com.sunxung.factoring.service.salescontractmanagement.ICSalesSignConfirmationElectronicInfoService;
import com.sunxung.factoring.service.salescontractmanagement.ICSalesSignConfirmationService;
import com.sunxung.factoring.service.salescontractmanagement.SalesContractService;
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.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * <p>
 * 销售合同销售-签署确认表 服务实现类
 * </p>
 *
 * @author yafan
 * @since 2023-11-28
 */
@Service("sales_sign_confirmationService")
public class CSalesSignConfirmationServiceImpl extends ServiceImpl<CSalesSignConfirmationMapper, CSalesSignConfirmation>
        implements ICSalesSignConfirmationService {

    @Autowired
    private ICSalesSignConfirmationElectronicInfoService signConfirmationElectronicInfoService;
    @Autowired
    private BusinessProcessingLogService businessProcessingLogService;
    @Autowired
    private SalesContractService salesContractService;
    @Autowired
    private UserService userService;
    @Resource(name = "projectInformationService")
    private IProjectInformationService projectInformationService;
    @Autowired
    private FlowableService flowableService;
    @Autowired
    private IElectronicSignaturePersonalService electronicSignaturePersonalService;
    @Autowired
    private ISysAttachmentRefService sysAttachmentRefService;
    @Autowired
    private FileStorageService fileStorageService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void doAdd(CSalesSignConfirmation signConfirmation) {

        ThreadLocalUtil.setUser(userService.getByLoginName("admin"));

        CSalesSignConfirmation old = getById(signConfirmation.getId());
        old.setRemark(signConfirmation.getRemark());
        old.setSignConclusion(signConfirmation.getSignConclusion());
        updateById(old);
        List<CSalesSignConfirmationElectronicInfo> signConfirmationElectronicInfos = signConfirmationElectronicInfoService
                .list(new QueryWrapper<CSalesSignConfirmationElectronicInfo>().eq("c_sales_sign_confirmation_id", signConfirmation.getId()));
        boolean anyMatch = signConfirmationElectronicInfos.stream().anyMatch(r -> r.getSignStatus().equals(0));
        if (anyMatch) {
            throw new ValidatorException(CodeUtil.FAIL, "合同尚未签署完成，无法提交！");
        }

        //流程处理
        String processKey = ConstantUtil.SALES_CONTRACT;
        String assigneeKey = ConstantUtil.SALES_SIGN_CONFIRMATION_APPROVAL + ConstantUtil._CANDIDATE;

        CSalesContract salesContractManagement = salesContractService.getById(signConfirmation.getBusinessKey());

        //taskId
        BusinessProcessingLog lastLog = businessProcessingLogService.getByBusinessTypeBusinessKey(processKey, salesContractManagement.getId());
        String taskId = lastLog.getHistoricTaskId();

        List<Long> legalSpecialists = userService.findUserIdByRole(ConstantUtil.LEGAL_SPECIALIST);
        if (legalSpecialists == null || legalSpecialists.size() == 0) {
            throw new ValidatorException(CodeUtil.FAIL, ConstantUtil.OPERATION_SPECIALIST + "角色内无任何用户！");
        }
        List<String> legalIds = legalSpecialists.stream().map(c -> c.toString()).collect(Collectors.toList());


        Map<String, Object> procVariables = new HashMap<>(1);
        procVariables.put(assigneeKey, legalIds);
        Map<String, Object> msgVariables = new HashMap<>(2);
        //项目信息
        ProjectInformation projectInformation = projectInformationService
                .getOne(new QueryWrapper<ProjectInformation>()
                        .eq("business_number", salesContractManagement.getBusinessNumber()));
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_TITLE, projectInformation.getProjectName());
        msgVariables.put(ConstantUtil.FLOWABLE_MSG_CONTENT,
                "业务编号为" + salesContractManagement.getBusinessNumber() + "”的项目已inOut“"
                        + ConstantConversionUtil.flowBusinessKeyNames.get(processKey) + "—formBusiness”阶段，");
        Boolean success = flowableService.completeMyTask(taskId, salesContractManagement, procVariables, null, signConfirmation.getId(),
                msgVariables, processKey, legalSpecialists);
        if (success == null || !success) {
            throw new ValidatorException(CodeUtil.FAIL, "销售合同-业务录入时出错啦！");
        }
    }

    @Override
    public CSalesSignConfirmation getView(Long id) {


        CSalesSignConfirmation signConfirmation = getById(id);
        if (signConfirmation != null) {
            //电子签信息
            List<CSalesSignConfirmationElectronicInfo> signElectronicInfos = signConfirmationElectronicInfoService
                    .list(new QueryWrapper<CSalesSignConfirmationElectronicInfo>().eq("c_sales_sign_confirmation_id", id));
            if (CollectionUtil.isNotEmpty(signElectronicInfos)) {

                CSalesSignConfirmationElectronicInfo confirmationElectronicInfo = signElectronicInfos.get(0);
                //签署人信息
                ElectronicSignaturePersonal signaturePersonal = electronicSignaturePersonalService
                        .getById(confirmationElectronicInfo.getElectronicSignaturePersonalId());
                signConfirmation.setElectronicSignaturePersonal(signaturePersonal);
                signConfirmation.setSignConfirmationElectronicInfos(signElectronicInfos);

                //已签署文件
                List<FileStorage> fileStorageList = new ArrayList<>();
                signElectronicInfos.forEach(signElectronicInfo -> {
                    AttachmentDto attachmentDto = AttachmentDto.builder()
                            .setEntityId(signElectronicInfo.getId())
                            .setChildEnum(FileModuleDict.ChildEnum.SIGN_CONFIRM_BACK_FILE)
                            .build();
                    List<FileStorage> files = sysAttachmentRefService.getFiles(attachmentDto);
                    if (CollectionUtil.isNotEmpty(files)) {
                        fileStorageList.add(files.get(0));
                    }
                });
                signConfirmation.setFiles(fileStorageList);
            }

        }
        return signConfirmation;
    }

    @Override
    public void urlJob() {
        Date date = new Date();
        Date dateTime = DateUtil.offsetDay(date, -6);
        List<CSalesSignConfirmationElectronicInfo> signElectronicInfos = signConfirmationElectronicInfoService.lambdaQuery().eq(CSalesSignConfirmationElectronicInfo::getSignStatus, 0).list();
        if (CollectionUtil.isNotEmpty(signElectronicInfos)) {
            for (CSalesSignConfirmationElectronicInfo signElectronicInfo : signElectronicInfos) {
                CSalesSignConfirmation salesSignConfirmation = lambdaQuery().eq(CSalesSignConfirmation::getId, signElectronicInfo.getcSalesSignConfirmationId()).one();
                if (salesSignConfirmation.getShortContractLinkCreate().compareTo(dateTime) < 1) {
                    String shortUrl = ElectronicSignatureUtil.shortUrl(null, salesSignConfirmation.getShortContractLink());
                    salesSignConfirmation.setShortContractLink(shortUrl);
                    salesSignConfirmation.setShortContractLinkCreate(date);
                    updateById(salesSignConfirmation);
                }
            }
        }
    }
}
