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

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.itextpdf.text.pdf.PdfReader;
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.entity.customerinformation.ElectronicSignaturePersonal;
import com.sunxung.factoring.entity.electronicsignature.FddSignData;
import com.sunxung.factoring.entity.project.BusinessProcessingLog;
import com.sunxung.factoring.entity.project.ProjectInformation;
import com.sunxung.factoring.entity.salescontractmanagement.*;
import com.sunxung.factoring.entity.salescontractmanagement.vo.SalesSignConfirmVo;
import com.sunxung.factoring.entity.sys.FileStorage;
import com.sunxung.factoring.mapper.salescontractmanagement.CSalesSupplementSignConfirmationMapper;
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.ICSalesContractSupplementBasicInfoService;
import com.sunxung.factoring.service.salescontractmanagement.ICSalesSupplementSignConfirmationElectronicInfoService;
import com.sunxung.factoring.service.salescontractmanagement.ICSalesSupplementSignConfirmationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunxung.factoring.service.salescontractmanagement.SalesContractService;
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.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 销售合同变更-签署确认表 服务实现类
 * </p>
 *
 * @author yafan
 * @since 2023-12-13
 */
@Service("supplement_sign_confirmationService")
public class CSalesSupplementSignConfirmationServiceImpl extends ServiceImpl<CSalesSupplementSignConfirmationMapper, CSalesSupplementSignConfirmation>
        implements ICSalesSupplementSignConfirmationService {

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


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

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

        CSalesSupplementSignConfirmation old = getById(signConfirmation.getId());
        old.setRemark(signConfirmation.getRemark());
        old.setSignConclusion(signConfirmation.getSignConclusion());
        updateById(old);
        List<CSalesSupplementSignConfirmationElectronicInfo> signConfirmationElectronicInfos = salesSupplementSignConfirmationElectronicInfoService
                .list(new QueryWrapper<CSalesSupplementSignConfirmationElectronicInfo>()
                        .eq("c_sales_supplement_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_CHANGE_PROCESS;
        String assigneeKey = ConstantUtil.SUPPLEMENT_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 CSalesSupplementSignConfirmation getView(Long id) {

        CSalesSupplementSignConfirmation signConfirmation = getById(id);
        if (signConfirmation != null) {
            //电子签信息
            List<CSalesSupplementSignConfirmationElectronicInfo> signElectronicInfos =
                    salesSupplementSignConfirmationElectronicInfoService
                    .list(new QueryWrapper<CSalesSupplementSignConfirmationElectronicInfo>()
                            .eq("c_sales_supplement_sign_confirmation_id", id));
            if (CollectionUtil.isNotEmpty(signElectronicInfos)) {

                CSalesSupplementSignConfirmationElectronicInfo confirmationElectronicInfo = signElectronicInfos.get(0);
                //签署人信息
                ElectronicSignaturePersonal signaturePersonal = electronicSignaturePersonalService
                        .getById(confirmationElectronicInfo.getElectronicSignaturePersonalId());
                signConfirmation.setSignConfirmationElectronicInfos(signElectronicInfos);
                signConfirmation.setElectronicSignaturePersonal(signaturePersonal);
                //已签署文件
                List<FileStorage> fileStorageList = new ArrayList<>();
                signElectronicInfos.forEach(signElectronicInfo->{
                    AttachmentDto attachmentDto = AttachmentDto.builder()
                            .setEntityId(id)
                            .setChildEnum(FileModuleDict.ChildEnum.SALES_SUPPLEMENT_SIGN_CONFIRM_BACK_FILE)
                            .build();
                    fileStorageList.addAll(sysAttachmentRefService.getFiles(attachmentDto));

                });
                signConfirmation.setFiles(fileStorageList);

            }
        }
        return signConfirmation;
    }

    //向法大大上传合同信息
    @Override
    public CSalesSupplementSignConfirmation uploadContract(CSalesSupplementSignConfirmation salesSignConfirmation) {

        ElectronicSignaturePersonal electronicSignaturePersonal = salesSignConfirmation.getElectronicSignaturePersonal();
        List<CSalesSupplementSignConfirmationElectronicInfo> signElectronicInfos = salesSignConfirmation.getSignConfirmationElectronicInfos();

        if (electronicSignaturePersonal.getAuthStatus().equals(1)) {
            List<FddSignData> fddSignDataList = new ArrayList();
            if (com.github.pagehelper.util.StringUtil.isEmpty(salesSignConfirmation.getContractLink())) {
                for (CSalesSupplementSignConfirmationElectronicInfo signConfirmationElectronicInfo : signElectronicInfos) {
                    if (signConfirmationElectronicInfo.getSignStatus() == 0) {
                        //将文件转换为PDF在上传法大大
                        FileStorage fileStorage = fileStorageService.get(signConfirmationElectronicInfo.getFileId());
                        File file = new File(fileStorage.getAbsolutePath());
                        String fileType = fileStorage.getFileType();
                        String newPath = file.getAbsolutePath().replace(fileType, ".pdf");
                        File pdfFile;
                        //只支持图片和excel转换
                        if (fileType.equals(".pdf")) {
                            pdfFile = file;
                        } else if (fileType.equals(".xlsx") || fileType.equals(".xls")) {
                            pdfFile = OfficeConverterUtil.office2Pdf(file.getAbsolutePath(), newPath);
                        } else if (fileType.equals(".jpg") || fileType.equals(".png") || fileType.equals(".jpeg") || fileType.equals(".bmp")) {
                            PdfUtil.convert(file.getAbsolutePath(), newPath);
                            pdfFile = new File(newPath);
                        } else {
                            throw new ValidatorException(CodeUtil.FAIL, "文件类型错误！");
                        }
                        PdfReader pdfReader = null;
                        try {
                            pdfReader = new PdfReader(new FileInputStream(pdfFile));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        int pages = pdfReader.getNumberOfPages();
                        //上传合同
                        String contractId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
                        String docTitle = fileStorage.getOriginalName();
                        String transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
                        ElectronicSignatureUtil.uploadContract(contractId, docTitle, pdfFile);
                        //批量手动签署
                        FddSignData fddSignData = new FddSignData();
                        fddSignData.setContractId(contractId);
                        fddSignData.setContractType("sales");
                        String page = String.valueOf(pages - 1);
                        fddSignData.setSearchLocation(page);
                        fddSignData.setTransactionId(transactionId);
                        fddSignDataList.add(fddSignData);

                        signConfirmationElectronicInfo.setContractId(contractId);
                        signConfirmationElectronicInfo.setTransactionId(transactionId);
                        salesSupplementSignConfirmationElectronicInfoService.updateById(signConfirmationElectronicInfo);
                    }
                }
                if (CollectionUtil.isNotEmpty(fddSignDataList)) {
                    String contractLink = ElectronicSignatureUtil.batchSignUrlSearchLocation(electronicSignaturePersonal.getFddCustomerId(), fddSignDataList, "签署确认批量签署");
                    //合同链接
                    String shortUrl = ElectronicSignatureUtil.shortUrl(null, contractLink);
                    salesSignConfirmation.setContractLink(contractLink);
                    salesSignConfirmation.setShortContractLink(shortUrl);
                    salesSignConfirmation.setShortContractLinkCreate(new Date());
                    updateById(salesSignConfirmation);
                }

            }
        }
        return salesSignConfirmation;
    }

    @Override
    public void urlJob() {
        Date date = new Date();
        Date dateTime = DateUtil.offsetDay(date, -6);
        List<CSalesSupplementSignConfirmationElectronicInfo> cSalesSupplementSignConfirmationElectronicInfos = salesSupplementSignConfirmationElectronicInfoService.lambdaQuery().eq(CSalesSupplementSignConfirmationElectronicInfo::getSignStatus, 0).list();
        if(CollectionUtil.isNotEmpty(cSalesSupplementSignConfirmationElectronicInfos)){
            for (CSalesSupplementSignConfirmationElectronicInfo cSalesSupplementSignConfirmationElectronicInfo : cSalesSupplementSignConfirmationElectronicInfos) {
                CSalesSupplementSignConfirmation cSalesSupplementSignConfirmation = lambdaQuery().eq(CSalesSupplementSignConfirmation::getId, cSalesSupplementSignConfirmationElectronicInfo.getcSalesSupplementSignConfirmationId()).one();
                if (cSalesSupplementSignConfirmation.getShortContractLinkCreate().compareTo(dateTime) < 1) {
                    String shortUrl = ElectronicSignatureUtil.shortUrl(null, cSalesSupplementSignConfirmation.getShortContractLink());
                    cSalesSupplementSignConfirmation.setShortContractLink(shortUrl);
                    cSalesSupplementSignConfirmation.setShortContractLinkCreate(date);
                    updateById(cSalesSupplementSignConfirmation);
                }
            }
        }
    }
}
