package com.zehong.system.service.impl.debitSettlement;

import com.zehong.common.core.exception.BusinessException;
import com.zehong.common.utils.SecurityUtils;
import com.zehong.system.domain.TAccount;
import com.zehong.system.domain.TCashOperate;
import com.zehong.system.domain.TDebitCredit;
import com.zehong.system.mapper.TAccountMapper;
import com.zehong.system.mapper.TCashOperateMapper;
import com.zehong.system.service.impl.tradeSettlement.AutoSettlePendingPayment;
import io.jsonwebtoken.lang.Collections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;

/**
 * @author geng
 * 借贷账户结算
 */
@Component
public class SettlementDebit {

    private static final Logger log = LoggerFactory.getLogger(SettlementDebit.class);

    @Resource
    private TAccountMapper tAccountMapper;

    @Resource
    private TCashOperateMapper cashOperateMapper;

    private TDebitCredit tDebitCredit;

    @Autowired
    private AutoSettlePendingPayment autoSettlePendingPayment;

    /**
     * 借贷结算
     * @param tDebitCredit 借贷实体
     */
    public void settlementDebit(TDebitCredit tDebitCredit){
        this.tDebitCredit = tDebitCredit;
        //出借部门结算
        lendDeptSettlement(tDebitCredit.getLendDeptId(),tDebitCredit.getLittleTotal(),"5");
        //借贷部门结算
        debitDeptSettlement(tDebitCredit.getDebitDeptId(),tDebitCredit.getLittleTotal(),"6");
    }

    /**
     * 还款
     * @param tDebitCredit 借贷实体
     */
    public void repayment(TDebitCredit tDebitCredit){
        this.tDebitCredit = tDebitCredit;
        //计算还款日期
        //long time = tDebitCredit.getExpectedRepaymentDate().getTime() - tDebitCredit.getSumInterestDate().getTime();
        //2023-08-25 修改为根据实际还款日计算
        long time = new Date().getTime() - tDebitCredit.getSumInterestDate().getTime();
        long days = Math.round(((double)time) / 1000 / 60 / 60 / 24);
        //还款部门
        BigDecimal repayAmount = tDebitCredit.getLittleTotal().multiply( new BigDecimal(1 + 0.08/360 * days)).setScale(2, RoundingMode.HALF_UP);
        tDebitCredit.setRealPaymentDate(new Date());
        tDebitCredit.setRealPaymentAcount(repayAmount);
        lendDeptSettlement(tDebitCredit.getDebitDeptId(),repayAmount,"7");
        //还款进账部门
        debitDeptSettlement(tDebitCredit.getLendDeptId(),repayAmount,"8");
    }

    /**
     * 出借部门结算
     * @param deptId 部门账户
     * @param amount 金额
     * @param operatorType 操作类型
     */
    private void lendDeptSettlement(Long deptId, BigDecimal amount,String operatorType){
        TAccount account = getAccountInfo(deptId);
        if(account.getAbleAmount().compareTo(amount) == -1){
            throw new BusinessException("出借或还款账户金额不足！");
        }
        updateAccount(account,amount.negate(),operatorType);
    }

    /**
     * 借贷部门结算
     * @param deptId 部门账户
     * @param amount 金额
     * @param operatorType 操作类型
     */
    private void debitDeptSettlement(Long deptId, BigDecimal amount,String operatorType){
        TAccount account = getAccountInfo(deptId);
        //更新可用额度
        updateAccount(account,amount,operatorType);
        autoSettlePendingPayment.autoSettlePendingPayment(amount,account,deptId);
    }


    /**
     * 更新账户可用金额
     * @param tAccount 账户信息
     * @param  amount 账户变动金额
     * @param operatorType 操作类型
     */
    private void updateAccount(TAccount tAccount, BigDecimal amount,String operatorType){
        if(amount.compareTo(BigDecimal.ZERO) == 0) return;
        tAccount.setAbleAmount(tAccount.getAbleAmount().add(amount));
        tAccount.setUpdateTime(new Date());
        tAccountMapper.updateTAccount(tAccount);
        //更新资金变动日志
        TCashOperate operate = OperatorParam(tAccount.getDeptId(),amount,this.tDebitCredit.getDebitId().toString());
        //1.交易单 2.借支单 3.外部采购单 4.借贷单
        operate.setDocumentType("4");
        operate.setOperateType(operatorType);
        cashOperateMapper.insertTCashOperate(operate);
    }

    /**
     * 获取账户信息
     * @param deptId
     * @return
     */
    private TAccount getAccountInfo(Long deptId){
        TAccount tAccount = new TAccount();
        tAccount.setDeptId(deptId);
        List<TAccount> accounts =  tAccountMapper.selectTAccountList(tAccount);
        if(Collections.isEmpty(accounts)){
            log.error("交易部门资金账户不能为空，部门id:" + deptId);
            throw new BusinessException("交易部门资金账户不能为空!");
        }
        return accounts.get(0);
    }


    /**
     *
     * @param deptId 部门id
     * @param amount 变动金额
     * @param receiptNum 单据号
     * @return
     */
    private TCashOperate OperatorParam (Long deptId,BigDecimal amount,String receiptNum){
        TCashOperate operate = new TCashOperate();
        operate.setOperateDeptId(deptId);
        operate.setOperateAmount(amount.compareTo(BigDecimal.ZERO) == 1?amount:amount.abs());
        operate.setOperateTime(new Date());
        operate.setRelationDoc(receiptNum);
        operate.setOperatePersonId(SecurityUtils.getLoginUser().getUser().getUserId());
        return operate;
    }

}
