package com.inkasso.factoring.purchManagement.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.Rows;
import com.deepoove.poi.data.TableRenderData;
import com.deepoove.poi.data.Tables;
import com.deepoove.poi.data.style.BorderStyle;
import com.github.pagehelper.util.StringUtil;
import com.inkasso.adapter.exception.BusinessException;
import com.inkasso.adapter.util.CodeUtil;
import com.inkasso.adapter.util.CollectionUtil;
import com.inkasso.factoring.biddingManagement.entity.CBiddingBasicInfo;
import com.inkasso.factoring.biddingManagement.service.ICBiddingBasicInfoService;
import com.inkasso.factoring.common.util.ElectronicSignatureUtil;
import com.inkasso.factoring.common.util.WordWriter;
import com.inkasso.factoring.creditmanagement.entity.Enterprise;
import com.inkasso.factoring.creditmanagement.entity.ProjectInformation;
import com.inkasso.factoring.creditmanagement.entity.SupplierInfo;
import com.inkasso.factoring.creditmanagement.service.IEnterpriseService;
import com.inkasso.factoring.creditmanagement.service.IProjectInformationService;
import com.inkasso.factoring.creditmanagement.service.ISupplierInfoService;
import com.inkasso.factoring.electronicSignature.entity.FddSignData;
import com.inkasso.factoring.file.entity.FileStorageDO;
import com.inkasso.factoring.purchManagement.entity.*;
import com.inkasso.factoring.purchManagement.dao.CPurchContractSupplementElectronicInfoMapper;
import com.inkasso.factoring.purchManagement.entity.vo.PurchContractChangeTemplateVo;
import com.inkasso.factoring.purchManagement.entity.vo.PurchContractSupplementSignConfirmVo;
import com.inkasso.factoring.purchManagement.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.inkasso.factoring.tradingPlatform.entity.Platform;
import com.inkasso.factoring.tradingPlatform.service.ITradingPlatformService;
import org.apache.poi.xwpf.usermodel.XWPFTable;
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.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 采购合同-补充电子合同信息表 服务实现类
 * </p>
 *
 * @author yafan
 * @since 2023-12-15
 */
@Service
public class CPurchContractSupplementElectronicInfoServiceImpl extends ServiceImpl<CPurchContractSupplementElectronicInfoMapper, CPurchContractSupplementElectronicInfo>
        implements ICPurchContractSupplementElectronicInfoService {

    @Autowired
    private ICPurchContractManagementService purchContractService;
    @Autowired
    private ICPurchContractSupplementInfoService supplementInfoService;
    @Autowired
    private IProjectInformationService projectInformationService;
    @Autowired
    private ICPurchContractBasicInfoService purchContractBasicInfoService;
    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private ICBiddingBasicInfoService biddingBasicInfoService;
    @Autowired
    private ITradingPlatformService platformService;
    @Autowired
    private IUploadPurchSupplementContractService uploadPurchSupplementContractService;
    @Autowired
    private IPurchContractSupplementApprovalService purchContractSupplementApprovalService;
    @Autowired
    private ICPurchContractSupplementGoodsInfoService supplementGoodsInfoService;
    @Autowired
    private ISupplierInfoService supplierInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PurchContractSupplementSignConfirmVo doSign(Long businessKey) throws IOException {

        PurchContractSupplementSignConfirmVo supplementSignConfirmVo = new PurchContractSupplementSignConfirmVo();

        CPurchContractManagement purchContractManagement = purchContractService.getById(businessKey);
        ProjectInformation projectInformation = projectInformationService.getOne(new QueryWrapper<ProjectInformation>()
                .eq("business_number",purchContractManagement.getBusinessNumber()));
        List<CPurchContractSupplementInfo> purchContractSupplementInfos = supplementInfoService.lambdaQuery()
                .eq(CPurchContractSupplementInfo::getcPurchContractManagementId, purchContractManagement.getId())
                .orderByDesc(CPurchContractSupplementInfo::getGmtCreate)
                .list();

        if (purchContractSupplementInfos == null || purchContractSupplementInfos.size() == 0) {
            throw new BusinessException(CodeUtil.FAIL, "未查到该变更信息");
        }

        CPurchContractSupplementInfo supplementInfo = purchContractSupplementInfos.get(0);

        CPurchContractBasicInfo latestBasicInfo = purchContractBasicInfoService.getOne(new QueryWrapper<CPurchContractBasicInfo>()
                .eq("c_purch_contract_management_id",businessKey));
        supplementSignConfirmVo.setBasicId(latestBasicInfo.getId());

        SupplierInfo supplierInfo = supplierInfoService.getById(purchContractManagement.getSupplierId());
        Enterprise supplier = enterpriseService.getById(supplierInfo.getcEnterpriseId());
        supplementSignConfirmVo.setSupplier(supplier);
        //获取合同对应的最新签署信息
        List<CPurchContractSupplementElectronicInfo> supplementElectronicInfos = lambdaQuery()
                .eq(CPurchContractSupplementElectronicInfo::getcPurchContractSupplementInfoId, supplementInfo.getId()).list();
        if (CollectionUtil.isEmpty(supplementElectronicInfos)) {

            List<CPurchContractSupplementElectronicInfo> purchContractSupplementElectronicInfos = new ArrayList<>();

            List<FddSignData> fddSignDataList = new ArrayList<FddSignData>();

            List<PurchContractSupplementApproval> purchContractSupplementApprovals = purchContractSupplementApprovalService
                    .lambdaQuery()
                    .eq(PurchContractSupplementApproval::getPurchContractSupplementInfoId, supplementInfo.getId())
                    .orderByDesc(PurchContractSupplementApproval::getGmtCreate).list();
            //取最新的
            PurchContractSupplementApproval purchContractSupplementApproval = purchContractSupplementApprovals.get(0);

//            if (purchContractSupplementApproval.getUseContract().equals(1)) {
//                AttachmentDto attachmentDto = AttachmentDto.builder()
//                        .setEntityId(purchContractSupplementApproval.getId())
//                        .setChildEnum(FileModuleDict.ChildEnum.PURCHASE_CONTRACT_SUPPLEMENT_MAKE_FILE)
//                        .build();
//                //只有一个文件
//                List<FileStorageDO> files = sysAttachmentRefService.getFiles(attachmentDto);
//                FileStorageDO fileStorage;
//                if (CollectionUtil.isNotEmpty(files)) {
//                    fileStorage = files.get(0);
//                } else {
//                    throw new ValidatorException(CodeUtil.FAIL, "未查询到文件！");
//                }
//                File purchContractPdfFile = new File(fileStorage.getAbsolutePath());
//
//                uploadContract(supplementInfo, purchContractManagement, platform, purchContractPdfFile, taskId,
//                        purchContractSupplementElectronicInfos, fddSignDataList, supplementInfo.getSupplementContractNumber() + "-" + latestBasicInfo.getContractName() + "-补充合同");
//            }

            List<UploadPurchSupplementContract> uploadPurchSupplementContracts = uploadPurchSupplementContractService.lambdaQuery().eq(UploadPurchSupplementContract::getPurchContractApprovalId, purchContractSupplementApproval.getId()).list();
//            for (UploadPurchSupplementContract uploadPurchContract : uploadPurchSupplementContracts) {
//                AttachmentDto attachmentDtoUpload = AttachmentDto.builder()
//                        .setEntityId(uploadPurchContract.getId())
//                        .setChildEnum(FileModuleDict.ChildEnum.PURCHASE_SUPPLEMENT_CONTRACT_UPLOAD_CONTRACT_FILE)
//                        .build();
//                //只有一个文件
//                List<FileStorageDO> fileStorages = sysAttachmentRefService.getFiles(attachmentDtoUpload);
//                FileStorageDO uploadFileStorage = null;
//                if (CollectionUtil.isNotEmpty(fileStorages)) {
//                    uploadFileStorage = fileStorages.get(0);
//                } else {
//                    throw new ValidatorException(CodeUtil.FAIL, "未查询到文件！");
//                }
//                File uploadPdf = new File(uploadFileStorage.getAbsolutePath());
//                uploadContract(supplementInfo, purchContractManagement, platform, uploadPdf, taskId, purchContractSupplementElectronicInfos, fddSignDataList, supplementInfo.getSupplementContractNumber() + "-" + uploadPurchContract.getContractName());
//            }


            String contractLink = ElectronicSignatureUtil.manualBatchSign(supplier.getFddCustomerId(), fddSignDataList, supplementInfo.getSupplementContractNumber());

            purchContractSupplementElectronicInfos.forEach(electronicInfo -> {
                String shortUrl = ElectronicSignatureUtil.shortUrl(null, contractLink);
                electronicInfo.setShortContractLink(shortUrl);
                electronicInfo.setContractLink(contractLink);
                electronicInfo.setCertifyLink(supplier.getShortAuthUrl());
                //认证状态
                electronicInfo.setCertifyStatus(supplier.getAuthStatus());
                saveOrUpdate(electronicInfo);
            });
        }
        supplementSignConfirmVo.setElectronicInfoList(supplementElectronicInfos);
        return supplementSignConfirmVo;
    }

    private void uploadContract(CPurchContractSupplementInfo supplementInfo, CPurchContractManagement purchContractManagement, Platform platform, File file, String taskId, List<CPurchContractSupplementElectronicInfo> purchContractSupplementElectronicInfos, List<FddSignData> fddSignDataList, String contractName) {
        String contractId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        //String docTitle = supplementInfo.getSupplementContractNumber() + "采购合同补充合同";
        //上传合同
        String transactionIdAuto = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        ElectronicSignatureUtil.uploadContract(contractId, contractName, file);

        //采购合同自动签署
        String signKeyword = "xf";
        ElectronicSignatureUtil.autoSign(transactionIdAuto, contractId, platform.getFddCustomerId(), contractName, signKeyword);

        //批量手动签署 此处只有一个合同
        String transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        while (transactionId.contains("FDD")) {
            transactionId = UUID.randomUUID().toString().trim().replaceAll("-", "").toUpperCase();
        }

        FddSignData fddSignData = new FddSignData();
        fddSignData.setContractId(contractId);
        fddSignData.setContractType("Purch");
        fddSignData.setSignKeyword("gys");
        //transactionIdCache.saveObjBuildTransactionId(transactionId, "SIGNPURCHCHANGEFDD" + purchContractManagement.getId() + "FDD" + supplementInfo.getId() + "FDD" + taskId + "FDD" + ThreadLocalUtil.getUserId());
        fddSignData.setTransactionId(transactionId);
        fddSignDataList.add(fddSignData);


        CPurchContractSupplementElectronicInfo electronicInfo = new CPurchContractSupplementElectronicInfo();
        electronicInfo.setContractName(contractName);
        electronicInfo.setContractId(contractId);
        electronicInfo.setTransactionId(transactionId);
        electronicInfo.setSignStatus(false);
        electronicInfo.setCertifyStatus(false);
        electronicInfo.setShortContractLinkCreate(new Date());
        electronicInfo.setcPurchContractSupplementInfoId(supplementInfo.getId());
        purchContractSupplementElectronicInfos.add(electronicInfo);
    }

    /**
     * 制作合同：模板填充数据生成docx
     *
     * @param purchContractManagement
     * @param supplementInfo
     * @param otherConvention
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public File makePurchContractDocx(CPurchContractManagement purchContractManagement, CPurchContractBasicInfo purchContractBasicInfo,
                                      ProjectInformation projectInformation, Platform platform, CPurchContractSupplementInfo supplementInfo,
                                      String otherConvention) throws IOException {

        //获取对应供货商的企业客户信息
//        Enterprise supplierCustomer = enterpriseService.getById(purchContractManagement.getcSupplierInfoId());
        Enterprise supplierCustomer = null;
                //获取业务买方对应的企业客户信息
        Enterprise purchaserCustomer = enterpriseService.getById(projectInformation.getcEnterpriseId());
        DateTimeFormatter dfDateTime = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        List<CPurchContractSupplementGoodsInfo> goodsInfoList = supplementGoodsInfoService.lambdaQuery()
                .eq(CPurchContractSupplementGoodsInfo::getcPurchContractSupplementInfoId, supplementInfo.getId()).list();

        PurchContractChangeTemplateVo templateVo = new PurchContractChangeTemplateVo();
        //合同编号
        templateVo.setContractNumber(supplementInfo.getSupplementContractNumber());
        //买方
        templateVo.setBuyerName(platform.getPlatformName());
        //买方社会统一信用代码
        templateVo.setBuyerSocialCreditCode(platform.getSocialCreditCode());
        //卖方
        templateVo.setSeller(supplierCustomer.getCorporateName());
        //卖方社会统一信用代码
        templateVo.setSellerSocialCreditCode(supplierCustomer.getSocialCreditCode());
        //下游企业名称
        templateVo.setPurchaserName(purchaserCustomer.getCorporateName());
        //项目名称
        templateVo.setBusinessName(projectInformation.getProjectName());
        //原合同名称
        templateVo.setOldContractName(purchContractBasicInfo.getContractName());
        //原合同编号
        templateVo.setOldContractNumber(purchContractBasicInfo.getContractNumber());
        //货物信息
        templateVo.setGoods(buildTableRenderData(goodsInfoList));
        //甲方单位名称
        templateVo.setCompanyPlatformName(platform.getPlatformName());
        //甲方签订日期
        templateVo.setCompanyPlatformDate(LocalDateTime.now().format(dfDateTime));
        //乙方单位名称
        templateVo.setCompanySupplierName(supplierCustomer.getCorporateName());
        //乙方签订日期
        templateVo.setCompanySupplierDate(LocalDateTime.now().format(dfDateTime));
        //价格计算规则
        templateVo.setPriceRuleDetail(supplementInfo.getPriceRuleDetail());
        //合同生效时间
        templateVo.setContractEffectDate(DateUtil.format(supplementInfo.getContractEffectDate(), "yyyy年MM月dd日"));
        templateVo.setOtherConvention(StringUtil.isEmpty(otherConvention) ? "无" : otherConvention);


        return WordWriter.buildPurchContractChangeFile(supplementInfo.getSupplementContractNumber() + "-" + purchContractBasicInfo.getContractName() + "-补充合同", templateVo);
    }

    private TableRenderData buildTableRenderData(List<CPurchContractSupplementGoodsInfo> goodsInfoList) {
        Tables.TableBuilder tableBuilder = Tables.ofA4MediumWidth();

        BorderStyle borderStyle = new BorderStyle();
        borderStyle.setSize(5);
        borderStyle.setType(XWPFTable.XWPFBorderType.SINGLE);

        RowRenderData header = Rows.of("序号", "材料名称", "规格型号", "计量单位", "暂定数量", "暂定单价（元/吨）", "备注")
                .center()
                .textFontFamily("宋体")
                .textFontSize(10)
                .create();
        ;
        tableBuilder.addRow(header);
        int indexNumber = 1;
        BigDecimal unitsTotal = new BigDecimal(0);

        for (CPurchContractSupplementGoodsInfo goodsInfo : goodsInfoList) {
            RowRenderData data = Rows.of(indexNumber + "", goodsInfo.getGoodsName(), goodsInfo.getModelNumber(), goodsInfo.getUnits(), goodsInfo.getQuantity(), goodsInfo.getPrice(), goodsInfo.getRemark())
                    .center()
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(data);
            indexNumber++;
        }
        if (CollectionUtil.isEmpty(goodsInfoList)) {
            RowRenderData empty = Rows.of("无", null, null, null, null, null, null)
                    .center()
                    .textFontFamily("宋体")
                    .textFontSize(10)
                    .create();
            tableBuilder.addRow(empty);
        }

        TableRenderData goodsTable = tableBuilder.center().border(borderStyle).create();
        return goodsTable;
    }




}
