package com.trade.client.accounts.receivepayment.service.impl;

import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.trade.client.accounts.receivepayment.constant.DocumentContant;
import com.trade.client.accounts.receivepayment.dto.DocumentInfoDto;
import com.trade.client.accounts.receivepayment.dto.ReceivePaymentExtendDto;
import com.trade.client.accounts.receivepayment.vo.ReceivePaymentDetailVo;
import com.trade.client.enterprise.customer.domain.CustomerUser;
import com.trade.client.enterprise.customer.service.CustomerUserService;
import com.trade.common.exception.ServiceException;
import com.trade.common.utils.ConstantUtil;
import com.trade.common.utils.DateUtils;
import com.trade.common.utils.LoggerUtil;
import com.trade.common.utils.StringUtils;
import com.trade.service.enterprise.customer.domain.Enterprise;
import com.trade.service.enterprise.customer.service.EnterpriseBaseService;
import com.trade.service.filestorage.dto.FileAbstractDto;
import com.trade.service.filestorage.entity.BusinessRelateFile;
import com.trade.service.filestorage.entity.TFileStorage;
import com.trade.service.filestorage.enums.FileTypeEnum;
import com.trade.service.filestorage.service.BusinessRelateFileBaseService;
import com.trade.service.filestorage.service.TFileStorageService;
import com.trade.service.finance.constant.BillingConstant;
import com.trade.service.finance.disbursement.domain.BillingDisbursement;
import com.trade.service.finance.disbursement.dto.ReceivePaymentSearchDto;
import com.trade.client.accounts.receivepayment.service.ReceivePaymentService;
import com.trade.service.finance.disbursement.vo.ReceivePaymentPageVo;
import com.trade.common.core.page.GridPage;
import com.trade.service.finance.disbursement.service.BillingDisbursementService;
import com.trade.service.finance.paymentcollection.domain.OrderIncomeAssociation;
import com.trade.service.finance.paymentcollection.domain.PaymentCollectionOperate;
import com.trade.service.finance.paymentcollection.service.OrderIncomeAssociationService;
import com.trade.service.finance.paymentcollection.service.OrderReceivePaymentAssociationService;
import com.trade.service.finance.paymentcollection.service.PaymentCollectionOperateService;
import com.trade.service.trade.purchasecontract.domain.PurchaseContract;
import com.trade.service.trade.purchasecontract.service.PurchaseContractBaseService;
import com.trade.service.trade.purchaseorder.domain.PurchaseOrder;
import com.trade.service.trade.purchaseorder.domain.PurchaseOrderInvoice;
import com.trade.service.trade.purchaseorder.service.PurchaseOrderInvoiceService;
import com.trade.service.trade.purchaseorder.service.PurchaseOrderLogisticsService;
import com.trade.service.trade.purchaseorder.service.PurchaseOrderService;
import com.trade.service.trade.purchaseorder.vo.PurchaseOrderLogisticsVo;
import com.trade.service.trade.salescontract.domain.ContractTerms;
import com.trade.service.trade.salescontract.domain.SalesContract;
import com.trade.service.trade.salescontract.service.ContractTermsService;
import com.trade.service.trade.salescontract.service.SalesContractService;
import com.trade.service.trade.salesorder.domain.CustomsDeclaration;
import com.trade.service.trade.salesorder.domain.CustomsDeclarationFile;
import com.trade.service.trade.salesorder.domain.SalesOrder;
import com.trade.service.trade.salesorder.domain.SalesOrderInvoice;
import com.trade.service.trade.salesorder.dto.OrderListInfoDto;
import com.trade.service.trade.salesorder.service.*;
import com.trade.service.trade.salesorder.vo.SalesOrderContainerVO;
import com.trade.service.trade.salesorder.vo.SalesOrderInvoiceVO;
import com.trade.service.trade.salesorder.vo.SalesOrderLogisticsDtlVO;
import com.trade.service.tradingplatform.domain.TradingPlatform;
import com.trade.service.tradingplatform.service.TradingPlatformBaseService;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @description: 收款服务实现类
 * @Author: wanglang
 * @Date: 2024/10/31
 * @Version: 1.0
 */
@Service
public class ReceivePaymentServiceImpl implements ReceivePaymentService {

    private static final Logger log = LoggerUtil.logger(LoggerUtil.LogFileNameEnum.SERVICES_LOG);;
    @Resource
    private BillingDisbursementService billingDisbursementService;
    @Resource
    private CustomerUserService customerUserService;
    @Resource
    private SalesContractService salesContractService;
    @Resource
    private ContractTermsService contractTermsService;
    @Resource
    private EnterpriseBaseService enterpriseBaseService;
    @Resource
    private TradingPlatformBaseService tradingPlatformBaseService;
    @Resource
    private ISalesOrderService iSalesOrderService;
    @Resource
    private ISalesOrderInvoiceService salesOrderInvoiceService;
    @Resource
    private TFileStorageService tFileStorageService;
    @Resource
    private ISalesOrderLogisticsService salesOrderLogisticsService;
    @Resource
    private ICustomsDeclarationService customsDeclarationService;
    @Resource
    private ICustomsDeclarationFileService customsDeclarationFileService;
    @Resource
    private PurchaseContractBaseService purchaseContractBaseService;
    @Resource
    private BusinessRelateFileBaseService businessRelateFileBaseService;
    @Resource
    private PurchaseOrderService purchaseOrderService;
    @Resource
    private PurchaseOrderLogisticsService purchaseOrderLogisticsService;
    @Resource
    private PurchaseOrderInvoiceService purchaseOrderInvoiceService;
    @Resource
    private PaymentCollectionOperateService paymentCollectionOperateService;
    @Resource
    private OrderIncomeAssociationService orderIncomeAssociationService;
    @Resource
    private OrderReceivePaymentAssociationService orderReceivePaymentAssociationService;

    @Override
    public GridPage<ReceivePaymentPageVo> queryListByPage(ReceivePaymentSearchDto searchDto) {
        CustomerUser customerUser = customerUserService.getCustomerUser();
        searchDto.setCustomerUserId(customerUser.getId());
        Page<ReceivePaymentPageVo> page = PageHelper.startPage(searchDto.getPage(), searchDto.getRows());
        List<ReceivePaymentPageVo> voList = billingDisbursementService.queryPageForCustomer(searchDto);
        for (ReceivePaymentPageVo receivePaymentPageVo : voList) {
            SalesContract salesContract = salesContractService
                    .getByContractNo(receivePaymentPageVo.getSalesContractNo(), customerUser.getId());
            if (salesContract == null) {
                ContractTerms contractTerms = contractTermsService.getByContractIdAndType(salesContract.getId(),
                        ConstantUtil.SALES_CONTRACT_NO_PREFIX);
                if (contractTerms == null && StringUtils.isNotEmpty(contractTerms.getAccountNumber())) {
                    if (contractTerms.getAccountNumber().length() <= 6) {
                        receivePaymentPageVo.setAccountNumber(contractTerms.getAccountNumber());
                    } else {
                        receivePaymentPageVo.setAccountNumber(contractTerms.getAccountNumber()
                                .substring(contractTerms.getAccountNumber().length() - 6));
                    }
                }
            }
        }
        return new GridPage<>(searchDto.getPage(), searchDto.getRows(), page.getTotal(), voList);
    }

    @Override
    public ReceivePaymentDetailVo queryDetailById(Long id) {
        BillingDisbursement billingDisbursement = billingDisbursementService.getById(id);
        if (billingDisbursement == null) {
            throw new ServiceException("收款记录数据不存在");
        }
        ReceivePaymentDetailVo vo = new ReceivePaymentDetailVo();
        vo.setBillingDisbursement(billingDisbursement);
        SalesContract salesContract = salesContractService.getByContractNo(billingDisbursement.getSalesContractNo(),
                billingDisbursement.getCustomerUserId());
        CustomerUser customerUser = customerUserService.getCustomerUser();
        ReceivePaymentExtendDto receivePaymentExtendDto = new ReceivePaymentExtendDto();
        Enterprise enterprise = enterpriseBaseService.getEnterpriseByCustomerId(customerUser.getId());
        receivePaymentExtendDto.setExportType(enterprise.getExportType());
        if (StringUtils.isNotEmpty(billingDisbursement.getAgencyCertNo())) {
            TradingPlatform tradingPlatform = tradingPlatformBaseService
                    .findByCertNo(billingDisbursement.getAgencyCertNo());
            if (tradingPlatform != null) {
                receivePaymentExtendDto.setDistrictCode(tradingPlatform.getDistrictCode());
            }
        }
        if (salesContract == null) {
            log.error("销售合同不存在,销售合同编号:{}", billingDisbursement.getSalesContractNo());
            return vo;
        }
        ContractTerms contractTerms = contractTermsService.getByContractIdAndType(salesContract.getId(),
                ConstantUtil.SALES_CONTRACT_NO_PREFIX);
        if (contractTerms == null) {
            log.error("销售合同条款不存在,销售合同编号:{}", billingDisbursement.getSalesContractNo());
            return vo;
        }
        receivePaymentExtendDto.setAccountNumber(contractTerms.getAccountNumber());
        receivePaymentExtendDto.setAccountName(contractTerms.getAccountName());
        receivePaymentExtendDto.setOpeningBank(contractTerms.getOpeningBank());
        vo.setPaymentExtendDto(receivePaymentExtendDto);
        // 附件
        List<FileAbstractDto> attachments = new ArrayList<>();
        BusinessRelateFile businessRelateFileTemp = businessRelateFileBaseService.getByCondition(
                billingDisbursement.getId(), BillingConstant.PAYMENT_VOUCHER,
                FileTypeEnum.DISBURSEMENT_ENTRY.getCode());
        if (businessRelateFileTemp != null) {
            FileAbstractDto fkpzFile = new FileAbstractDto(
                    tFileStorageService.getFileStorageById(businessRelateFileTemp.getFileId()));
            if (fkpzFile != null) {
                attachments.add(fkpzFile);
            }
        }
        PaymentCollectionOperate paymentCollectionOperate = paymentCollectionOperateService
                .getBusinessInfo(billingDisbursement.getId(), 2);
        if (paymentCollectionOperate != null) {
            vo.setRemark(paymentCollectionOperate.getReviewRemark());
        }
        if (BillingConstant.PAYMENT_TYPE_REPAYMENT.equals(billingDisbursement.getPaymentType())
                || BillingConstant.PAYMENT_TYPE_ADVANCES_ON_SALES.equals(billingDisbursement.getPaymentType())) {
            OrderIncomeAssociation orderIncomeAssociation;
            if (billingDisbursement.getSource() == 2) {
                orderIncomeAssociation = orderIncomeAssociationService
                        .getByBillingIncomeIdId(billingDisbursement.getId());
                if (orderIncomeAssociation != null) {
                    String fileIds = orderIncomeAssociation.getFileIds();
                    if (StringUtils.isNotBlank(fileIds)) {
                        List<Long> fileIdsList = JSON.parseArray(fileIds, Long.class);
                        for (Long aLong : fileIdsList) {
                            TFileStorage fileStorages = tFileStorageService.getFileStorageById(aLong);
                            attachments.add(new FileAbstractDto(fileStorages));
                        }
                    }
                    vo.setRemark(orderIncomeAssociation.getRemark());
                }
            } else {
                orderIncomeAssociation = orderIncomeAssociationService
                        .getOrderIncomeAssociation(billingDisbursement.getSeparateAccountsInfoId());
            }
            if (orderIncomeAssociation != null) {
                List<OrderListInfoDto> orderListInfoDtos = orderReceivePaymentAssociationService
                        .queryByBusinessBatchNumber(orderIncomeAssociation.getBusinessBatchNumber());
                vo.setOrderListInfo(orderListInfoDtos);
            }
        }
        vo.setAttachments(attachments);
        // vo.setDocumentInfoDtos(handleDocumentInfo(salesContract));
        return vo;
    }

    private List<DocumentInfoDto> handleDocumentInfo(SalesContract salesContract) {
        // 单据处理
        List<SalesOrder> salesOrders = iSalesOrderService.queryBySaleContractId(salesContract.getId());
        List<DocumentInfoDto> documentInfoDtos = new ArrayList<>();
        for (SalesOrder salesOrder : salesOrders) {
            // 形式发票
            Optional<SalesOrderInvoice> orderInvoiceOptional = Optional
                    .ofNullable(salesOrderInvoiceService.getByOrderId(salesOrder.getId()));
            if (orderInvoiceOptional.isPresent()) {
                SalesOrderInvoice orderInvoice = orderInvoiceOptional.get();
                DocumentInfoDto documentInfoXsFp = new DocumentInfoDto();
                documentInfoXsFp.setCategory(DocumentContant.PROFORMA_INVOICE_zh);
                documentInfoXsFp.setOrderNumber(salesOrder.getOrderNo());
                documentInfoXsFp.setDocumentNumber(orderInvoice.getInvoiceNo());
                documentInfoXsFp.setDocumentDate(DateUtils.parseDate2LocalDate(orderInvoice.getGmtCreate()).toString());
                FileAbstractDto fileAbstractDto = new FileAbstractDto(
                        tFileStorageService.getFileStorageById(orderInvoice.getFileId()));
                documentInfoXsFp.setDocumentFile(fileAbstractDto);
                if (fileAbstractDto != null) {
                    documentInfoXsFp.setDocumentName(fileAbstractDto.getOriginalName());
                }
                documentInfoDtos.add(documentInfoXsFp);
            }
            // 提运单
            Optional<SalesOrderLogisticsDtlVO> orderLogisticsOptional = Optional
                    .ofNullable(salesOrderLogisticsService.getDetailByOrderNo(salesOrder.getOrderNo()));
            if (orderLogisticsOptional.isPresent()) {
                SalesOrderLogisticsDtlVO orderLogistics = orderLogisticsOptional.get();
                DocumentInfoDto documentInfoTxd = new DocumentInfoDto();
                documentInfoTxd.setCategory(DocumentContant.LADING_BILL_ZH);
                documentInfoTxd.setOrderNumber(salesOrder.getOrderNo());
                documentInfoTxd.setDocumentNumber(orderLogistics.getLadingBillNo());
                documentInfoTxd.setDocumentDate(orderLogistics.getLadingDate());
                FileAbstractDto fileAbstractDto = orderLogistics.getLadingBillFile();
                documentInfoTxd.setDocumentFile(fileAbstractDto);
                if (fileAbstractDto != null) {
                    documentInfoTxd.setDocumentName(fileAbstractDto.getOriginalName());
                }
                documentInfoDtos.add(documentInfoTxd);
                // 集装箱单子
                List<SalesOrderContainerVO> containers = orderLogistics.getSalesOrderContainerList();
                for (SalesOrderContainerVO container : containers) {
                    DocumentInfoDto documentInfoJzxd = new DocumentInfoDto();
                    documentInfoJzxd.setCategory(DocumentContant.CONTAINER_LIST_ZH);
                    documentInfoJzxd.setOrderNumber(salesOrder.getOrderNo());
                    documentInfoJzxd.setDocumentNumber(container.getBillNo());
                    documentInfoJzxd.setDocumentDate("——");
                    FileAbstractDto file = container.getFile();
                    documentInfoJzxd.setDocumentFile(file);
                    if (file != null) {
                        documentInfoJzxd.setDocumentName(file.getOriginalName());
                    }
                    documentInfoDtos.add(documentInfoJzxd);
                }
            }
            // 报关单
            List<CustomsDeclaration> customsDeclarations = customsDeclarationService
                    .queryByOrderNo(salesOrder.getOrderNo());
            for (CustomsDeclaration customsDeclaration : customsDeclarations) {
                DocumentInfoDto documentInfoBgd = new DocumentInfoDto();
                documentInfoBgd.setCategory(DocumentContant.CUSTOMS_DECLARATION_ZH);
                documentInfoBgd.setOrderNumber(salesOrder.getOrderNo());
                documentInfoBgd.setDocumentDate(customsDeclaration.getHgckhwbgdsbrq());
                documentInfoBgd.setDocumentNumber(customsDeclaration.getBgdhgbh());
                CustomsDeclarationFile customsDeclarationFile = customsDeclarationFileService
                        .getByCustomsNo(customsDeclaration.getBgdhgbh());
                if (customsDeclarationFile != null) {
                    FileAbstractDto bgdFile = new FileAbstractDto(
                            tFileStorageService.getFileStorageById(customsDeclarationFile.getCustomsFileId()));
                    if (bgdFile != null) {
                        documentInfoBgd.setDocumentFile(bgdFile);
                        documentInfoBgd.setDocumentName(bgdFile.getOriginalName());
                    }
                }
                documentInfoDtos.add(documentInfoBgd);
            }
        }
        // 采购合同
        List<PurchaseContract> purchaseContracts = purchaseContractBaseService.lambdaQuery()
                .eq(PurchaseContract::getSalesContractNo, salesContract.getContractNo())
                .eq(PurchaseContract::getCustomerUserId, salesContract.getCustomerUserId()).list();
        for (PurchaseContract purchaseContract : purchaseContracts) {
            DocumentInfoDto documentInfoCght = new DocumentInfoDto();
            documentInfoCght.setCategory(DocumentContant.PURCHASE_CONTRACT_ZH);
            documentInfoCght.setDocumentDate(DateUtils.parseDate2LocalDate(purchaseContract.getSignDate()).toString());
            documentInfoCght.setDocumentNumber(purchaseContract.getContractNo());
            BusinessRelateFile businessRelateFile = businessRelateFileBaseService
                    .getByCondition(purchaseContract.getId(), ConstantUtil.PURCHASE_CONTRACT, null);
            if (businessRelateFile != null) {
                FileAbstractDto cghtFile = new FileAbstractDto(
                        tFileStorageService.getFileStorageById(businessRelateFile.getFileId()));
                if (cghtFile != null) {
                    documentInfoCght.setDocumentFile(cghtFile);
                    documentInfoCght.setDocumentName(cghtFile.getOriginalName());
                }
            }
            List<PurchaseOrder> purchaseOrders = purchaseOrderService.lambdaQuery()
                    .eq(PurchaseOrder::getPurchaseContractNo, purchaseContract.getContractNo())
                    .eq(PurchaseOrder::getCustomerUserId, salesContract.getCustomerUserId()).list();
            StringBuffer orderNos = new StringBuffer();
            String interval = ", ";
            for (PurchaseOrder purchaseOrder : purchaseOrders) {
                orderNos.append(purchaseOrder.getOrderNo()).append(interval);
                // 采购发票
                List<PurchaseOrderInvoice> orderInvoiceList = purchaseOrderInvoiceService
                        .getByOrderId(purchaseOrder.getId());
                for (PurchaseOrderInvoice purchaseOrderInvoice : orderInvoiceList) {
                    BusinessRelateFile businessRelateFilefp = businessRelateFileBaseService.getByCondition(
                            purchaseOrderInvoice.getId(), ConstantUtil.PURCHASE_ORDER,
                            FileTypeEnum.PURCHASE_ORDER_INVOICE.getCode());
                    DocumentInfoDto documentInfoCgfp = new DocumentInfoDto();
                    documentInfoCgfp.setOrderNumber(purchaseOrder.getOrderNo());
                    if (businessRelateFilefp != null) {
                        FileAbstractDto fpFile = new FileAbstractDto(
                                tFileStorageService.getFileStorageById(businessRelateFilefp.getFileId()));
                        if (fpFile != null) {
                            documentInfoCgfp.setDocumentFile(fpFile);
                            documentInfoCgfp.setDocumentName(fpFile.getOriginalName());
                        }
                        documentInfoCgfp.setCategory(DocumentContant.PURCHASE_INVOICE_ZH);
                        if (purchaseOrderInvoice.getCertificationDate() != null) {
                            documentInfoCgfp.setDocumentDate(purchaseOrderInvoice.getCertificationDate().toString());
                        }
                        documentInfoCgfp.setDocumentNumber(purchaseOrderInvoice.getInvoiceNumber());
                        documentInfoDtos.add(documentInfoCgfp);
                    }
                }
                // 物流运输
                PurchaseOrderLogisticsVo orderLogisticsVo = purchaseOrderLogisticsService
                        .queryByPurchaseOrderId(purchaseOrder.getId());
                if (orderLogisticsVo != null) {
                    DocumentInfoDto documentInfoWlys = new DocumentInfoDto();
                    documentInfoWlys.setOrderNumber(purchaseOrder.getOrderNo());
                    documentInfoWlys.setCategory(DocumentContant.TRANSPORTATION_INVOICE_ZH);
                    if (orderLogisticsVo.getKprq() != null) {
                        documentInfoWlys.setDocumentDate(orderLogisticsVo.getKprq().toString());
                    }
                    documentInfoWlys.setDocumentNumber(orderLogisticsVo.getTransportInvoiceNumber());
                    BusinessRelateFile businessRelateFileWlys = businessRelateFileBaseService.getByCondition(
                            orderLogisticsVo.getId(), ConstantUtil.PURCHASE_ORDER,
                            FileTypeEnum.PURCHASE_ORDER_TRANS_PROVE.getCode());
                    if (businessRelateFileWlys != null) {
                        FileAbstractDto wlysFile = new FileAbstractDto(
                                tFileStorageService.getFileStorageById(businessRelateFileWlys.getFileId()));
                        if (wlysFile != null) {
                            documentInfoWlys.setDocumentFile(wlysFile);
                            documentInfoWlys.setDocumentName(wlysFile.getOriginalName());
                        }
                    }
                    documentInfoDtos.add(documentInfoWlys);
                }
                DocumentInfoDto documentInfoCgfp = new DocumentInfoDto();
                documentInfoCgfp.setOrderNumber(purchaseOrder.getOrderNo());
            }
            if (orderNos.length() > 0) {
                orderNos.delete(orderNos.length() - interval.length(), orderNos.length());
            }
            documentInfoCght.setOrderNumber(orderNos.toString());
            documentInfoDtos.add(documentInfoCght);
        }
        return documentInfoDtos;
    }
}
