/**
 * @filename:#BillingIncomeServiceImpl 2024-10-22
 * @project KJT v1.1.0 Copyright(c) 2024 wanglang Co. Ltd. All right reserved.
 */
package com.trade.service.finance.paymentcollection.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.trade.common.utils.DateUtils;
import com.trade.common.utils.LoggerUtil;
import com.trade.common.utils.StringUtils;

import com.trade.common.utils.uuid.BizNoUtil;
import com.trade.service.business.payableaccounts.domain.PayableAccounts;
import com.trade.service.business.separateaccounts.service.SeparateAccountsService;
import com.trade.service.finance.constant.BillingConstant;
import com.trade.service.finance.paymentcollection.domain.BillingIncome;
import com.trade.service.finance.paymentcollection.domain.BillingIncomeInfo;
import com.trade.service.finance.paymentcollection.domain.OrderIncomeAssociation;
import com.trade.service.finance.paymentcollection.domain.PaymentCollectionOperate;;
import com.trade.service.finance.paymentcollection.dto.BillingIncomeSearchDto;
import com.trade.service.finance.paymentcollection.dto.ExportTaxRefundDto;
import com.trade.service.finance.paymentcollection.dto.ExportTaxRefundV2Dto;
import com.trade.service.finance.paymentcollection.mapper.BillingIncomeMapper;
import com.trade.service.finance.paymentcollection.service.BillingIncomeInfoService;
import com.trade.service.finance.paymentcollection.service.BillingIncomeService;
import com.trade.service.finance.paymentcollection.service.PaymentCollectionOperateService;
import com.trade.service.finance.paymentcollection.vo.BillingIncomePageVo;
import com.trade.service.trade.salescontract.domain.SalesContract;
import com.trade.service.trade.salescontract.dto.SalesContractDto;
import com.trade.service.trade.salescontract.service.SalesContractService;
import com.trade.service.trade.salesorder.domain.CustomsDeclaration;
import com.trade.service.trade.salesorder.domain.SalesOrder;
import com.trade.service.trade.salesorder.service.ICustomsDeclarationService;
import com.trade.service.trade.salesorder.service.ISalesOrderService;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @Description:入账表服务实现
 * @version: v1.1.0
 * @author: wanglang
 */
@Service
public class BillingIncomeServiceImpl extends ServiceImpl<BillingIncomeMapper, BillingIncome> implements BillingIncomeService {

    private static final Logger log = LoggerUtil.logger(LoggerUtil.LogFileNameEnum.SERVICES_LOG);;
    @Resource
    private ICustomsDeclarationService customsDeclarationService;
    @Resource
    private ISalesOrderService salesOrderService;
    @Resource
    private SalesContractService salesContractService;
    @Resource
    private PaymentCollectionOperateService paymentCollectionOperateService;
    @Resource
    private BillingIncomeInfoService billingIncomeInfoService;
    @Resource
    private SeparateAccountsService separateAccountsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Deprecated
    public boolean saveExportTaxRefund(ExportTaxRefundDto exportTaxRefundDto) {
        CustomsDeclaration customsDeclaration = customsDeclarationService
                .getByBgdh(exportTaxRefundDto.getCustomsDeclarationNo());
        if (customsDeclaration == null || StringUtils.isEmpty(customsDeclaration.getSaleOrderNo())) {
            log.error("报关单号={}不存在", exportTaxRefundDto.getCustomsDeclarationNo());
            log.error("出口货物报关单号={}不存在", exportTaxRefundDto.getExportCustomsDeclarationNo());
            return false;
        }
        SalesOrder salesOrder = salesOrderService.getByOrderNo(customsDeclaration.getSaleOrderNo());
        if (salesOrder == null) {
            log.error("报关单号={},订单号={}订单不存在", exportTaxRefundDto.getCustomsDeclarationNo(),
                    customsDeclaration.getSaleOrderNo());
            log.error("出口货物报关单号={}", exportTaxRefundDto.getExportCustomsDeclarationNo());
            return false;
        }
        SalesContractDto salesContractDto = salesContractService.getSalesContractById(salesOrder.getSaleContractId());
        if (salesContractDto == null) {
            log.error("报关单号={},订单号={},销售合同id={}合同不存在", exportTaxRefundDto.getCustomsDeclarationNo(),
                    customsDeclaration.getSaleOrderNo(), salesOrder.getSaleContractId());
            log.error("出口货物报关单号={}", exportTaxRefundDto.getExportCustomsDeclarationNo());
            return false;
        }
        BillingIncome billingIncome = new BillingIncome();
        billingIncome.setSalesContractNo(salesContractDto.getContractNo());
        billingIncome.setCustomerUserId(salesOrder.getCustomerUserId());
        billingIncome.setActualAmount(exportTaxRefundDto.getRefundAmount());
        billingIncome.setApplyAmount(exportTaxRefundDto.getRefundAmount());
        billingIncome.setAgencyCertNo(salesContractDto.getAgencyCertNo());
        billingIncome.setAgencyEnterpriseName(salesContractDto.getAgencyEnterpriseName());
        billingIncome.setImporterCertNo(salesContractDto.getImporterCertNo());
        billingIncome.setImporterEnterpriseName(salesContractDto.getImporterEnterpriseName());
        billingIncome.setPaymentType(BillingConstant.PAYMENT_TYPE_TAX_REFUND);
        billingIncome.setPaymentWay(BillingConstant.PAYMENT_WAY_SYSTEM_ENTRY);
        billingIncome.setStatus(BillingConstant.ENTRY_STATUS_RECEIVED);
        billingIncome.setApplyEntryDate(LocalDate.now());
        billingIncome.setSaleOrderNo(customsDeclaration.getSaleOrderNo());
        this.save(billingIncome);
        BillingIncomeInfo billingIncomeInfo = new BillingIncomeInfo();
        billingIncomeInfo.setBillingIncomeId(billingIncome.getId());
        billingIncomeInfo.setCustomsDeclarationNo(exportTaxRefundDto.getCustomsDeclarationNo());
        billingIncomeInfo.setExportCustomsDeclarationNo(exportTaxRefundDto.getExportCustomsDeclarationNo());
        billingIncomeInfo.setDeclarationBatch(exportTaxRefundDto.getDeclarationBatch());
        billingIncomeInfo.setDeclarationMonthYear(exportTaxRefundDto.getDeclarationMonthYear());
        billingIncomeInfo.setAccountNumber(exportTaxRefundDto.getAccountNumber());
        billingIncomeInfoService.save(billingIncomeInfo);
        PaymentCollectionOperate paymentCollectionOperate = new PaymentCollectionOperate(billingIncome.getId(), 1);
        paymentCollectionOperate.setApplicant("系统");
        paymentCollectionOperate.setApplyDate(LocalDateTime.now());
        paymentCollectionOperateService.save(paymentCollectionOperate);
        separateAccountsService.saveSeparateAccounts(billingIncome, "系统");
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveExportTaxRefundV2(List<ExportTaxRefundV2Dto> exportTaxRefundDtos) {
        if (CollectionUtil.isEmpty(exportTaxRefundDtos)) {
            return false;
        }
        ExportTaxRefundV2Dto exportTaxRefundV2Dto = exportTaxRefundDtos.get(0);
        SalesContractDto salesContractDto = salesContractService
                .getSalesContractById(exportTaxRefundV2Dto.getSaleContractId());
        if (salesContractDto == null) {
            log.error("销售合同id={}合同不存在", exportTaxRefundV2Dto.getSaleContractId());
            return false;
        }
        for (ExportTaxRefundV2Dto exportTaxRefundDto : exportTaxRefundDtos) {
            BillingIncome billingIncome = new BillingIncome();
            billingIncome.setSalesContractNo(salesContractDto.getContractNo());
            billingIncome.setCustomerUserId(salesContractDto.getCustomerUserId());
            billingIncome.setActualAmount(exportTaxRefundDto.getRefundAmount());
            billingIncome.setApplyAmount(exportTaxRefundDto.getRefundAmount());
            billingIncome.setAgencyCertNo(salesContractDto.getAgencyCertNo());
            billingIncome.setAgencyEnterpriseName(salesContractDto.getAgencyEnterpriseName());
            billingIncome.setImporterCertNo(salesContractDto.getImporterCertNo());
            billingIncome.setImporterEnterpriseName(salesContractDto.getImporterEnterpriseName());
            billingIncome.setPaymentType(BillingConstant.PAYMENT_TYPE_TAX_REFUND);
            billingIncome.setPaymentWay(BillingConstant.PAYMENT_WAY_SYSTEM_ENTRY);
            billingIncome.setStatus(BillingConstant.ENTRY_STATUS_UNCONFIRMED);
            billingIncome.setPayerName("税务局");
            billingIncome.setPayerType(BillingConstant.PAYERTYPE_TAXATION_BUREAU);
            billingIncome.setPayeeType(BillingConstant.PAYEE_TYPE_AGENT);
            billingIncome.setPayeeName(salesContractDto.getAgencyEnterpriseName());
            billingIncome.setActualCurrency("CNY");
            billingIncome.setApplyEntryDate(exportTaxRefundDto.getEntryDate());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD);
            String dateString = LocalDate.now().format(formatter);
            billingIncome.setBusinessNumber(BizNoUtil.generateBusinessNumber(dateString, 5));
            this.save(billingIncome);
            BillingIncomeInfo billingIncomeInfo = new BillingIncomeInfo();
            billingIncomeInfo.setBillingIncomeId(billingIncome.getId());
            billingIncomeInfo.setDeclarationBatch(exportTaxRefundDto.getDeclarationBatch());
            billingIncomeInfo.setDeclarationMonthYear(exportTaxRefundDto.getDeclarationMonthYear());
            billingIncomeInfo.setDetailIds(JSON.toJSONString(exportTaxRefundDto.getDetailIds()));
            billingIncomeInfo.setAccountNumber(exportTaxRefundDto.getAccountNumber());
            billingIncomeInfoService.save(billingIncomeInfo);
            PaymentCollectionOperate paymentCollectionOperate = new PaymentCollectionOperate(billingIncome.getId(), 1);
            paymentCollectionOperate.setApplicant("系统");
            paymentCollectionOperate.setApplyDate(LocalDateTime.now());
            paymentCollectionOperateService.save(paymentCollectionOperate);
        }
        return true;
    }

    @Override
    public List<BillingIncomePageVo> findByPage(BillingIncomeSearchDto searchDto) {
        List<BillingIncomePageVo> billingIncomePageVos = this.baseMapper.selectByPage(searchDto);
        return billingIncomePageVos;
    }

    @Override
    public Long saveOrderIncome(OrderIncomeAssociation orderIncomeAssociation) {
        BillingIncome billingIncome = new BillingIncome();
        billingIncome.setSalesContractNo(orderIncomeAssociation.getSalesContractNo());
        billingIncome.setApplyAmount(orderIncomeAssociation.getReceivePayment());
        billingIncome.setApplyCurrency(orderIncomeAssociation.getCurrency());
        billingIncome.setTradeReceivableAmount(orderIncomeAssociation.getOriginalReceivePayment());
        billingIncome.setTradeReceivableCurrency(orderIncomeAssociation.getOriginalCurrency());
        SalesContractDto salesContractDto = salesContractService
                .getSalesContractById(orderIncomeAssociation.getSaleContractId());
        billingIncome.setCustomerUserId(salesContractDto.getCustomerUserId());
        billingIncome.setAgencyCertNo(salesContractDto.getAgencyCertNo());
        billingIncome.setAgencyEnterpriseName(salesContractDto.getAgencyEnterpriseName());
        billingIncome.setImporterCertNo(salesContractDto.getImporterCertNo());
        billingIncome.setImporterEnterpriseName(salesContractDto.getImporterEnterpriseName());
        billingIncome.setPaymentType(orderIncomeAssociation.getPaymentType());
        billingIncome.setPaymentWay(BillingConstant.PAYMENT_WAY_ENTRY_APPLY);
        billingIncome.setStatus(BillingConstant.ENTRY_STATUS_UNCONFIRMED);
        billingIncome.setPayerName(salesContractDto.getImporterEnterpriseName());
        billingIncome.setPayerType(BillingConstant.PAYERTYPE_IMPORTER);
        billingIncome.setPayeeType(BillingConstant.PAYEE_TYPE_AGENT);
        billingIncome.setPayeeName(salesContractDto.getAgencyEnterpriseName());
        billingIncome.setApplyEntryDate(orderIncomeAssociation.getExpectedPaymentDueDate());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD);
        String dateString = LocalDate.now().format(formatter);
        billingIncome.setBusinessNumber(BizNoUtil.generateBusinessNumber(dateString, 5));
        return billingIncome.getId();
    }

    @Override
    public Long savePayableAccountsIncome(PayableAccounts payableAccounts) {
        BillingIncome billingIncome = new BillingIncome();
        billingIncome.setSalesContractNo(payableAccounts.getSalesContractNo());
        billingIncome.setApplyAmount(payableAccounts.getPaymentAmount());
        billingIncome.setApplyCurrency(payableAccounts.getPaymentCurrency());
        // SalesContract salesContractDto = salesContractService.getByContractNo(payableAccounts.getSalesContractNo(),
        // payableAccounts.getCustomerUserId());
        billingIncome.setCustomerUserId(payableAccounts.getCustomerUserId());
        // billingIncome.setAgencyCertNo(salesContractDto.getAgencyCertNo());
        // billingIncome.setAgencyEnterpriseName(salesContractDto.getAgencyEnterpriseName());
        // billingIncome.setImporterCertNo(salesContractDto.getImporterCertNo());
        // billingIncome.setImporterEnterpriseName(salesContractDto.getImporterEnterpriseName());
        if (BillingConstant.PAYMENT_TYPE_TECHNOLOGY_SERVICE_FEE.equals(payableAccounts.getPaymentType())) {
            billingIncome.setPaymentType(BillingConstant.PAYMENT_TYPE_TECHNICAL_SERVICE_FEE);
        } else if (BillingConstant.PAYMENT_TYPE_TAX_REFUND_FEE.equals(payableAccounts.getPaymentType())) {
            billingIncome.setPaymentType(BillingConstant.PAYMENT_TYPE_EXPORT_TAX_REFUND_SERVICE_FEE);
        } else {
            billingIncome.setPaymentType(payableAccounts.getPaymentType());
        }
        billingIncome.setPaymentWay(BillingConstant.PAYMENT_WAY_ENTRY_APPLY);
        billingIncome.setStatus(BillingConstant.ENTRY_STATUS_UNCONFIRMED);
        billingIncome.setPayeeType(payableAccounts.getPayeeType());
        billingIncome.setPayeeName(payableAccounts.getPayeeName());
        billingIncome.setApplyEntryDate(LocalDate.now());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DateUtils.YYYYMMDD);
        String dateString = LocalDate.now().format(formatter);
        billingIncome.setBusinessNumber(BizNoUtil.generateBusinessNumber(dateString, 5));
        return billingIncome.getId();
    }
}
