package com.jwipc.finance.logic.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jwipc.api.dto.ErpApiResult;
import com.jwipc.contract.client.ContractDetailClient;
import com.jwipc.contract.client.ContractPaymentApplyClient;
import com.jwipc.exception.DaoException;
import com.jwipc.finance.constant.PaymentOaClient;
import com.jwipc.finance.convert.PaymentChangeConvert;
import com.jwipc.finance.dto.PayChangeToOpenDTO;
import com.jwipc.finance.dto.PayImportToOpenResultDTO;
import com.jwipc.finance.dto.PaymentChangeParamDTO;
import com.jwipc.finance.entity.PaymentAdvanceApply;
import com.jwipc.finance.entity.PaymentChange;
import com.jwipc.finance.entity.PaymentCodApply;
import com.jwipc.finance.logic.PaymentChangeLogic;
import com.jwipc.finance.model.po.PaymentChangePO;
import com.jwipc.finance.model.query.PaymentChangeQuery;
import com.jwipc.finance.service.IPaymentAdvanceApplyService;
import com.jwipc.finance.service.IPaymentChangeService;
import com.jwipc.finance.service.IPaymentCodApplyService;
import com.jwipc.page.PageUtil;
import com.jwipc.page.PageView;
import com.jwipc.security.LoginUtil;
import com.jwipc.sys.client.SequenceClient;
import com.jwipc.sys.util.FinancialShareUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author shenyang.ou
 * @date 2025/11/25 19:55
 * @desc
 */
@Service
@RequiredArgsConstructor
public class PaymentChangeLogicImpl implements PaymentChangeLogic {
    private final IPaymentCodApplyService paymentCodApplyService;
    private final IPaymentAdvanceApplyService paymentAdvanceApplyService;
    private final PaymentChangeConvert paymentChangeConvert;
    private final IPaymentChangeService paymentChangeService;
    private final PaymentOaClient paymentOaClient;
    private final SequenceClient sequenceClient;
    private final FinancialShareUtil financialShareUtil;
    private final ContractPaymentApplyClient contractPaymentApplyClient;

    @Override
    @Transactional
    public void saveOrUpdate(PaymentChangeParamDTO param) {
        String companyCode = "";
        String appNo = "";
        String supplierCode = "";
        if (param.getBusinessType()==0){
            PaymentCodApply paymentCodApply = paymentCodApplyService.getById(param.getAppId());
            if (ObjectUtil.isNull(paymentCodApply)) {
                throw new DaoException("付款申请单不存在");
            }
            if (paymentCodApply.getStatus() != 9) {
                throw new DaoException("付款申请单不是付款失败状态，无法发起变更");
            }
            companyCode = paymentCodApply.getCompanyCode();
            appNo = paymentCodApply.getCpApplyNo();
            supplierCode = paymentCodApply.getSupplierCode();
            paymentCodApply.setChangeStatus(0);
//            paymentCodApply.setStatus(7);
//            paymentCodApply.setPaymentCompanyName(param.getPaymentCompanyName());
//            paymentCodApply.setSupBankName(param.getSupBankName());
//            paymentCodApply.setSupBankAccount(param.getSupBankAccount());
//            paymentCodApply.setSupBankCode(param.getSupBankCode());
//            paymentCodApply.setBankCode(param.getSupBankCode());
//            paymentCodApply.setBankInterCode(param.getBankInterCode());
//            paymentCodApply.setBankAddress(param.getBankAddress());
            paymentCodApplyService.updateById(paymentCodApply);
        //资产合同付款申请变更单
        }else if (param.getBusinessType()==3) {
//            if (ObjectUtil.isNull(paymentCodApply)) {
//                throw new DaoException("付款申请单不存在");
//            }
//            if (paymentCodApply.getStatus() != 9) {
//                throw new DaoException("付款申请单不是付款失败状态，无法发起变更");
//            }
            companyCode = param.getCompanyCode();
            appNo = param.getCpApplyNo();
            supplierCode = param.getSupplierCode();
//            paymentCodApply.setChangeStatus(0);
            contractPaymentApplyClient.updateContractPaymentStatus(param.getAppId(), "0");
        }else {
            PaymentAdvanceApply paymentCodApply = paymentAdvanceApplyService.getById(param.getAppId());
            if (ObjectUtil.isNull(paymentCodApply)) {
                throw new DaoException("预付款申请单不存在");
            }
            if (paymentCodApply.getStatus() != 9) {
                throw new DaoException("预付款申请单不是付款失败状态，无法发起变更");
            }
            companyCode = paymentCodApply.getCompanyCode();
            appNo = paymentCodApply.getApApplyNo();
            supplierCode = paymentCodApply.getSupplierCode();
            paymentCodApply.setChangeStatus(0);
//            paymentCodApply.setStatus(7);
//            paymentCodApply.setPaymentCompanyName(param.getPaymentCompanyName());
//            paymentCodApply.setSupBankName(param.getSupBankName());
//            paymentCodApply.setSupBankAccount(param.getSupBankAccount());
//            paymentCodApply.setSupBankCode(param.getSupBankCode());
//            paymentCodApply.setBankCode(param.getSupBankCode());
//            paymentCodApply.setBankInterCode(param.getBankInterCode());
//            paymentCodApply.setBankAddress(param.getBankAddress());
            paymentAdvanceApplyService.updateById(paymentCodApply);
        }

        Long id = ObjectUtil.isNotNull(param.getChangeId())?param.getChangeId():IdWorker.getId();
        PaymentChange old = paymentChangeService.getById(param.getChangeId());
        String paymentChangeNo = ObjectUtil.isNotNull(param.getChangeId())?old.getChangeNo():sequenceClient.createSequenceNo("payment_change_no");

        //提交到共享
        String accessToken = financialShareUtil.getShareAccessToken();
        PayChangeToOpenDTO payImportToOpenDTO = new PayChangeToOpenDTO();
        PayChangeToOpenDTO.DataHead dataHead = new PayChangeToOpenDTO.DataHead();
        // 单据编号
        dataHead.setBillno(paymentChangeNo);
        dataHead.setOrg_number(companyCode);
        dataHead.setCreatetime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
//        dataHead.setCreator_number(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        dataHead.setCreator_number(LoginUtil.getAccount());
        dataHead.setSourcebillno(appNo);
        dataHead.setRemark(param.getRemark());

        List<PayChangeToOpenDTO.Entry> entryList = new ArrayList<>();
        PayChangeToOpenDTO.Entry entry = new PayChangeToOpenDTO.Entry();
        //TODO 往来银行(变更前).编码（行号）
        entry.setE_bebankbefore_number(param.getSupBankCodeOld());
        // 往来银行(变更后).编码（行号）
        entry.setE_bebank_number(param.getSupBankCode());
        // 往来户.编码
        entry.setE_asstact_number(supplierCode);
        // 变更明细.分录id
        entry.setE_srcentryids(String.valueOf(id));
        // 变更明细.往来账户(变更前)
        entry.setE_assacctbefore(param.getSupBankAccountOld());
        //变更明细.往来账户(变更后)
        entry.setE_assacct(param.getSupBankAccount());
        //变更明细.往来类型 [bd_supplier:供应商, bos_user:人员, bos_org:公司, bd_customer:客户]
        entry.setE_asstacttype("bd_supplier");
        // 变更明细.银行地址(变更前)
        entry.setM4p4_bank_address_be(param.getBankAddressOld());
        //变更明细.银行地址(变更后)
        entry.setM4p4_bank_address_af(param.getBankAddressOld());
        // 变更明细.银行代码(变更前)
        entry.setM4p4_bank_code_be(param.getSupBankCodeOld());
        //变更明细.银行代码(变更后)
        entry.setM4p4_bank_code_af(param.getSupBankCode());
        // 变更明细.银行国际代码(变更前)
        entry.setM4p4_swift_code_be(param.getBankInterCodeOld());
        //变更明细.银行国际代码(变更后)
        entry.setM4p4_swift_code_af(param.getBankInterCode());
        entry.setM4p4_account_title_be(param.getPaymentCompanyNameOld());
        entry.setM4p4_account_title(param.getPaymentCompanyName());
        entryList.add(entry);
        dataHead.setEntry(entryList);

        payImportToOpenDTO.setData(dataHead);
        ErpApiResult<PayImportToOpenResultDTO> result = paymentOaClient.payChangeToOpen(accessToken, payImportToOpenDTO);
        if (!result.getStatus()) {
            throw new DaoException("共享系统接口报错：" + result.getMessage());
        }

        PaymentChange paymentChange = paymentChangeConvert.toPaymentChange(param);
        String shareId = result.getData().getResult().get(0).getId();
        String shareCode = result.getData().getResult().get(0).getNumber();
        if (ObjectUtil.isNull(param.getChangeId())){
            paymentChange.setAppNo(appNo);
            paymentChange.setChangeNo(paymentChangeNo);
            paymentChange.setCreateUser(LoginUtil.getUserId());
            paymentChange.setCreateTime(LocalDateTime.now());
            paymentChange.setShareNo(shareCode);
            paymentChange.setShareId(shareId);
            paymentChangeService.save(paymentChange);
        }else {
            paymentChange.setId(param.getChangeId());
            paymentChange.setUpdateUser(LoginUtil.getUserId());
            paymentChange.setUpdateTime(LocalDateTime.now());
            paymentChange.setShareNo(shareCode);
            paymentChange.setShareId(shareId);
            paymentChangeService.updateById(paymentChange);
        }
        if (param.getBusinessType()==3) {
//            contractPaymentApplyClient.updateContractPaymentStatus(param.getAppId(), "7");
        }
    }

    @Override
    public PageView findByPage(PaymentChangeQuery query) {
        final Page<PaymentChange> dbPage = PageUtil.toPage(query);

        List<PaymentChangePO> paymentChanges = paymentChangeService.findPageByQuery(dbPage, query);

        return PageUtil.getPV(paymentChanges, dbPage.getTotal());
    }
}
