package com.trade.admin.finance.disbursement.service.impl;

import com.alibaba.fastjson2.JSON;
import com.trade.admin.business.payment.domain.PaymentBasic;
import com.trade.admin.business.payment.domain.PaymentBasicInfo;
import com.trade.admin.business.payment.service.PaymentBasicInfoService;
import com.trade.admin.business.payment.service.PaymentBasicService;
import com.trade.admin.finance.disbursement.dto.ConfirmedDisbursementDto;
import com.trade.admin.finance.disbursement.service.BBillingDisbursementService;
import com.trade.admin.finance.disbursement.vo.BillingDisbursementDetail;
import com.trade.admin.finance.paymentcollection.dto.BankAccountDto;
import com.trade.admin.system.security.utils.SecurityUtils;
import com.trade.common.core.page.GridPage;
import com.trade.common.exception.ServiceException;
import com.trade.common.utils.StringUtils;
import com.trade.common.utils.bean.BeanCopyUtils;
import com.trade.common.utils.uuid.BizNoUtil;
import com.trade.service.business.separateaccounts.domain.SeparateAccounts;
import com.trade.service.business.separateaccounts.domain.SeparateAccountsInfo;
import com.trade.service.business.separateaccounts.service.SeparateAccountsInfoService;
import com.trade.service.business.separateaccounts.service.SeparateAccountsService;
import com.trade.service.filestorage.entity.BusinessRelateFile;
import com.trade.service.filestorage.enums.FileTypeEnum;
import com.trade.service.filestorage.service.BusinessRelateFileBaseService;
import com.trade.service.finance.constant.BillingConstant;
import com.trade.service.finance.disbursement.domain.BillingDisbursement;
import com.trade.service.finance.disbursement.dto.DisbursementSearchDto;
import com.trade.service.finance.disbursement.service.BillingDisbursementService;
import com.trade.service.finance.disbursement.vo.BillingDisbursementPageVo;
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.service.OrderIncomeAssociationService;
import com.trade.service.finance.paymentcollection.service.PaymentCollectionOperateService;
import com.trade.service.trade.salesorder.constant.SaleOrderConstant;
import com.trade.service.trade.salesorder.domain.SalesOrder;
import com.trade.service.trade.salesorder.dto.SalesOrderReceiveExtendDto;
import com.trade.service.trade.salesorder.service.ISalesOrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;

/**
 * @description: 出账服务实现类
 * @Author: wanglang
 * @Date: 2024/10/28 20:05
 * @Version: 1.0
 */
@Service
public class BBillingDisbursementServiceImpl implements BBillingDisbursementService {

    @Resource
    private BillingDisbursementService billingDisbursementService;
    @Resource
    private PaymentCollectionOperateService paymentCollectionOperateService;
    @Resource
    private BusinessRelateFileBaseService businessRelateFileBaseService;
    @Resource
    private PaymentBasicInfoService paymentBasicInfoService;
    @Resource
    private PaymentBasicService paymentBasicService;
    @Resource
    private SeparateAccountsInfoService separateAccountsInfoService;
    @Resource
    private SeparateAccountsService separateAccountsService;
    @Resource
    private OrderIncomeAssociationService orderIncomeAssociationService;
    @Resource
    private ISalesOrderService iSalesOrderService;

    @Override
    public boolean saveDisbursement(PaymentBasic paymentBasic, PaymentBasicInfo paymentBasicInfo, String operator) {
        BillingDisbursement billingDisbursement = BeanCopyUtils.copy(paymentBasic, BillingDisbursement.class);
        billingDisbursement.setId(null);
        billingDisbursement.setPaymentBasicId(paymentBasic.getId());
        billingDisbursement.setPaymentAmount(paymentBasicInfo.getPaymentAmount());
        billingDisbursement.setPaymentCurrency(paymentBasicInfo.getPaymentCurrency());
        // billingDisbursement.setPaymentDate(paymentBasicInfo.getPaymentDate());
        billingDisbursement.setStatus(BillingConstant.DISBURSEMENT_STATUS_UNCONFIRMED);
        billingDisbursementService.save(billingDisbursement);
        PaymentCollectionOperate paymentCollectionOperate = new PaymentCollectionOperate(billingDisbursement.getId(),
                2);
        paymentCollectionOperate.setApplicant(operator);
        paymentCollectionOperate.setApplyDate(LocalDateTime.now());
        paymentCollectionOperateService.save(paymentCollectionOperate);
        return true;
    }

    @Override
    public GridPage<BillingDisbursementPageVo> queryListByPage(DisbursementSearchDto searchDto) {
        return billingDisbursementService.queryListByPage(searchDto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmedDisbursement(ConfirmedDisbursementDto confirmedDisbursementDto) {
        BillingDisbursement disbursement = billingDisbursementService.getById(confirmedDisbursementDto.getId());
        if (disbursement == null) {
            throw new ServiceException("出账记录不存在");
        }
        String userNickName = SecurityUtils.getUserNickName();
        disbursement.setTransactionNumber(confirmedDisbursementDto.getTransactionNumber());
        disbursement.setPaymentDate(confirmedDisbursementDto.getPaymentDate());
        disbursement.setVoucherNo(confirmedDisbursementDto.getVoucherNo());
        disbursement.setAccountNumber(confirmedDisbursementDto.getAccountNumber());
        PaymentCollectionOperate paymentCollectionOperate = paymentCollectionOperateService
                .getBusinessInfo(disbursement.getId(), 2);
        if (paymentCollectionOperate != null) {
            paymentCollectionOperate.setReviewDate(LocalDateTime.now());
            paymentCollectionOperate.setReviewer(userNickName);
            paymentCollectionOperate.setReviewRemark(confirmedDisbursementDto.getRemark());
            paymentCollectionOperateService.updateById(paymentCollectionOperate);
        } else {
            paymentCollectionOperate = new PaymentCollectionOperate(disbursement.getId(), 2);
            paymentCollectionOperate.setReviewRemark(confirmedDisbursementDto.getRemark());
            paymentCollectionOperate.setReviewer(userNickName);
            paymentCollectionOperate.setReviewDate(LocalDateTime.now());
            paymentCollectionOperateService.save(paymentCollectionOperate);
        }
        // 附件
        if (confirmedDisbursementDto.getFileId() != null) {
            BusinessRelateFile businessRelateFile = new BusinessRelateFile();
            businessRelateFile.setFileId(confirmedDisbursementDto.getFileId());
            businessRelateFile.setBelongId(disbursement.getId());
            businessRelateFile.setBelongType(BillingConstant.PAYMENT_VOUCHER);
            businessRelateFile.setFileType(FileTypeEnum.DISBURSEMENT_ENTRY.getCode());
            businessRelateFileBaseService.addBusinessRelateFiles(Collections.singletonList(businessRelateFile));
        }
        disbursement.setStatus(BillingConstant.DISBURSEMENT_STATUS_CONFIRMED);
        billingDisbursementService.save(disbursement);
        if (BillingConstant.PAYMENT_TYPE_REPAYMENT.equals(disbursement.getPaymentType())
                || BillingConstant.PAYMENT_TYPE_ADVANCES_ON_SALES.equals(disbursement.getPaymentType())) {
            SeparateAccountsInfo separateAccountsInfo = separateAccountsInfoService
                    .getById(disbursement.getSeparateAccountsInfoId());
            if (separateAccountsInfo != null) {
                SeparateAccounts separateAccounts = separateAccountsService
                        .getById(separateAccountsInfo.getSeparateAccountsId());
                OrderIncomeAssociation orderIncomeAssociation = orderIncomeAssociationService
                        .getByBillingIncomeIdId(separateAccounts.getBillingIncomeId());
                if (orderIncomeAssociation != null) {
                    String orderInfo = orderIncomeAssociation.getOrderInfo();
                    if (StringUtils.isNotEmpty(orderInfo)) {
                        List<SalesOrderReceiveExtendDto> salesOrderInfo = JSON.parseArray(orderInfo,
                                SalesOrderReceiveExtendDto.class);
                        for (SalesOrderReceiveExtendDto salesOrderReceiveExtendDto : salesOrderInfo) {
                            SalesOrder salesOrder = iSalesOrderService
                                    .getById(salesOrderReceiveExtendDto.getSalesOrderId());
                            int orderStatus = SaleOrderConstant.ORDER_STATUS_END;
                            if (salesOrder.getStatus().equals(SaleOrderConstant.ORDER_STATUS_PARTIAL_COLLECTION)) {
                                orderStatus = SaleOrderConstant.ORDER_STATUS_PARTIALLY_COMPLETED;
                            }
                            iSalesOrderService.updateSalesOrderAndGoodsStatus(salesOrderReceiveExtendDto, orderStatus,
                                    SaleOrderConstant.GOODS_STATUS_TRANSFERRED_OUT, 4);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public BillingDisbursementDetail queryDetail(Long id) {
        BillingDisbursement billingDisbursement = billingDisbursementService.getById(id);
        if (billingDisbursement == null) {
            throw new ServiceException("出账记录不存在");
        }
        BillingDisbursementDetail billingDisbursementDetail = new BillingDisbursementDetail();
        billingDisbursementDetail.setBillingDisbursement(billingDisbursement);
        businessRelateFileBaseService.fillBizObjFiles(billingDisbursementDetail, billingDisbursement.getId(),
                BillingConstant.PAYMENT_VOUCHER, FileTypeEnum.DISBURSEMENT_ENTRY.getCode());
        PaymentCollectionOperate paymentCollectionOperate = paymentCollectionOperateService
                .getBusinessInfo(billingDisbursement.getId(), 2);
        billingDisbursementDetail.setPaymentCollectionOperate(paymentCollectionOperate);
        PaymentBasicInfo paymentBasicInfo = paymentBasicInfoService
                .getByCodePaymentBasicId(billingDisbursement.getPaymentBasicId());
        if (paymentBasicInfo != null) {
            BankAccountDto paymentAccount = new BankAccountDto();
            paymentAccount.setAccountNumber(paymentBasicInfo.getAccountNumber());
            paymentAccount.setAccountName(paymentBasicInfo.getAccountName());
            paymentAccount.setOpeningBank(paymentBasicInfo.getOpeningBank());
            billingDisbursementDetail.setPaymentAccount(paymentAccount);
        }
        PaymentBasic paymentBasic = paymentBasicService.getById(billingDisbursement.getPaymentBasicId());
        if (paymentBasic != null) {
            SeparateAccountsInfo separateAccountsInfo = separateAccountsInfoService
                    .getById(paymentBasic.getSeparateAccountsInfoId());
            if (separateAccountsInfo != null) {
                BankAccountDto receivePaymentAccount = new BankAccountDto();
                receivePaymentAccount.setAccountNumber(separateAccountsInfo.getAccountNumber());
                receivePaymentAccount.setAccountName(separateAccountsInfo.getAccountName());
                receivePaymentAccount.setOpeningBank(separateAccountsInfo.getOpeningBank());
                billingDisbursementDetail.setPaymentAccount(receivePaymentAccount);
            }
        }
        return billingDisbursementDetail;
    }

    @Override
    public BillingDisbursementDetail queryDetailV2(Long id) {
        BillingDisbursement billingDisbursement = billingDisbursementService.getById(id);
        if (billingDisbursement == null) {
            throw new ServiceException("出账记录不存在");
        }
        BillingDisbursementDetail billingDisbursementDetail = new BillingDisbursementDetail();
        billingDisbursementDetail.setBillingDisbursement(billingDisbursement);
        businessRelateFileBaseService.fillBizObjFiles(billingDisbursementDetail, billingDisbursement.getId(),
                BillingConstant.PAYMENT_VOUCHER, FileTypeEnum.DISBURSEMENT_ENTRY.getCode());
        PaymentCollectionOperate paymentCollectionOperate = paymentCollectionOperateService
                .getBusinessInfo(billingDisbursement.getId(), 2);
        billingDisbursementDetail.setPaymentCollectionOperate(paymentCollectionOperate);
        SeparateAccountsInfo separateAccountsInfo = separateAccountsInfoService
                .getById(billingDisbursement.getSeparateAccountsInfoId());
        if (separateAccountsInfo != null) {
            BankAccountDto receivePaymentAccount = new BankAccountDto();
            receivePaymentAccount.setAccountNumber(separateAccountsInfo.getAccountNumber());
            receivePaymentAccount.setAccountName(separateAccountsInfo.getAccountName());
            receivePaymentAccount.setOpeningBank(separateAccountsInfo.getOpeningBank());
            billingDisbursementDetail.setPaymentAccount(receivePaymentAccount);
        }
        return billingDisbursementDetail;
    }

    @Override
    public boolean saveBillingDisbursement(SeparateAccounts separateAccounts, SeparateAccountsInfo separateAccountsInfo,
            String operator) {
        BillingDisbursement billingDisbursement = BeanCopyUtils.copy(separateAccounts, BillingDisbursement.class);
        billingDisbursement.setId(null);
        billingDisbursement.setSeparateAccountsInfoId(separateAccountsInfo.getId());
        billingDisbursement.setEntryBusinessNumber(separateAccounts.getBusinessNumber());
        billingDisbursement.setPaymentAmount(separateAccountsInfo.getLedgerAmount());
        billingDisbursement.setPaymentCurrency(separateAccountsInfo.getLedgerCurrency());
        billingDisbursement.setTradeParticipantsIdentifier(separateAccountsInfo.getTradeParticipantsIdentifier());
        // billingDisbursement.setPaymentDate(paymentBasicInfo.getPaymentDate());
        billingDisbursement.setStatus(BillingConstant.DISBURSEMENT_STATUS_UNCONFIRMED);
        billingDisbursement.setPaymentType(separateAccountsInfo.getLedgerType());
        if (BillingConstant.PAYMENT_TYPE_TAX_REFUND.equals(separateAccounts.getPaymentType())) {
            billingDisbursement.setPayeeType(BillingConstant.PAYEE_TYPE_CUSTOMER);
            billingDisbursement.setPayerType(BillingConstant.PAYERTYPE_AGENT);
        }
        billingDisbursement.setPayerName(separateAccounts.getAgencyEnterpriseName());
        billingDisbursement.setSource(1);
        billingDisbursement
                .setBusinessNumber(BizNoUtil.generateBusinessNumber(separateAccounts.getBusinessNumber(), 2));
        billingDisbursementService.save(billingDisbursement);
        PaymentCollectionOperate paymentCollectionOperate = new PaymentCollectionOperate(billingDisbursement.getId(),
                2);
        paymentCollectionOperate.setApplicant(operator);
        paymentCollectionOperate.setApplyDate(LocalDateTime.now());
        paymentCollectionOperateService.save(paymentCollectionOperate);
        return true;
    }
}
