package com.clx.performance.service.impl.loan;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.performance.dao.OwnerBindCardRecordDao;
import com.clx.performance.dao.loan.BankTradeDao;
import com.clx.performance.dao.loan.OwnerLoanAccountDao;
import com.clx.performance.dao.loan.OwnerLoanRecordDao;
import com.clx.performance.dao.loan.OwnerRepaymentDao;
import com.clx.performance.enums.OwnerAccountEnum;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.loan.BankTradeEnum;
import com.clx.performance.enums.loan.OwnerLoanRecordEnum;
import com.clx.performance.enums.loan.OwnerRePaymentEnum;
import com.clx.performance.extranal.user.OwnerInfoService;
import com.clx.performance.model.OwnerBindCardRecord;
import com.clx.performance.model.loan.BankTrade;
import com.clx.performance.model.loan.OwnerLoanAccount;
import com.clx.performance.model.loan.OwnerLoanRecord;
import com.clx.performance.model.loan.OwnerRepayment;
import com.clx.performance.param.pc.loan.carrier.OwnerRepaymentParam;
import com.clx.performance.param.pc.loan.carrier.PageOwnerLoanAccountParam;
import com.clx.performance.service.loan.OwnerLoanAccountService;
import com.clx.performance.service.thirdparty.nbbank.NbBankService;
import com.clx.performance.struct.loan.OwnerLoanAccountStruct;
import com.clx.performance.vo.pc.loan.carrier.CarrierOwnerLoanAccountVO;
import com.clx.performance.vo.pc.loan.owner.OwnerAccountVO;
import com.clx.performance.vo.pc.nbbank.NbBankOrderPayResultVO;
import com.clx.user.vo.feign.OwnerInfoFeignVO;
import com.msl.common.base.Optional;
import com.msl.common.convertor.aspect.UnitCovert;
import com.msl.common.exception.ServiceSystemException;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * @author kavin
 * Date 2024-01-20
 * Time 13:31
 */
@Service
@Slf4j
@AllArgsConstructor
public class OwnerLoanAccountServiceImpl implements OwnerLoanAccountService {

    private final OwnerLoanAccountDao ownerLoanAccountDao;

    private final OwnerLoanAccountStruct ownerLoanAccountStruct;

    private final OwnerInfoService ownerInfoService;

    private final OwnerRepaymentDao ownerRepaymentDao;

    private final NbBankService bankService;

    private final BankTradeDao bankTradeDao;

    private final OwnerLoanRecordDao ownerLoanRecordDao;

    private final OwnerBindCardRecordDao ownerBindCardRecordDao;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void openOwnerLoanAccount(Long ownerUserNo, String ownerUserName, String mobile) {
        OwnerLoanAccount entity = new OwnerLoanAccount();
        entity.setOwnerUserNo(ownerUserNo);
        entity.setMobile(mobile);
        entity.setOwnerUserName(ownerUserName);
        entity.setFundingAccountBalance(BigDecimal.ZERO);
        entity.setFundingFrozenBalance(BigDecimal.ZERO);
        entity.setFundingUsableBalance(BigDecimal.ZERO);
        entity.setFundingArrears(BigDecimal.ZERO);

        entity.setVirtuallyArrears(BigDecimal.ZERO);
        entity.setVirtuallyAccountBalance(BigDecimal.ZERO);
        entity.setVirtuallyUsableBalance(BigDecimal.ZERO);
        entity.setVirtuallyFrozenBalance(BigDecimal.ZERO);
        entity.setAccountType(OwnerAccountEnum.AccountTypeStatus.LOAN_ACCOUNT.getCode());
        entity.setCreateBy("系统");
        ownerLoanAccountDao.saveEntity(entity);
    }

    @Override
    @UnitCovert(param = false)
    public IPage<CarrierOwnerLoanAccountVO> pageOwnerLoanAccount(PageOwnerLoanAccountParam param) {
        return ownerLoanAccountDao.pageByParam(param);
    }

    @Override
    public OwnerAccountVO getOwnerLoanAccount() {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();
        Optional<OwnerLoanAccount> optional = ownerLoanAccountDao.getOneByField(OwnerLoanAccount::getOwnerUserNo,
                loginUserInfo.getUserNo());
        if (!optional.isPresent()) {
            return OwnerAccountVO.builder().openAccount(0).build();
        }
        OwnerLoanAccount ownerLoanAccount = optional.get();
        OwnerAccountVO ownerAccountVO = ownerLoanAccountStruct.convertVO(ownerLoanAccount);
        ownerAccountVO.setOpenAccount(1);
        return ownerAccountVO;
    }


    @Override
    public void ownerRepayment(OwnerRepaymentParam param) {
        OwnerRepayment ownerRepayment = ownerRepaymentDao.getOneByField(OwnerRepayment::getRepaymentNo, param.getRepaymentNo()).get();
        if (!ownerRepayment.getStatus().equals(OwnerRePaymentEnum.Status.PAY_WAIT.getCode())) {
            throw new ServiceSystemException(PerformanceResultEnum.OWNER_LOAN_RECORD_PAY_STATUS_ERROR);
        }
        OwnerLoanRecord ownerLoanRecord = ownerLoanRecordDao.getOneByField(OwnerLoanRecord::getLoanNo, ownerRepayment.getLoanNo()).get();
        BankTrade bankTrade = new BankTrade();
        OwnerBindCardRecord ownerBindCardRecord = ownerBindCardRecordDao.getOwnerBindCardByUserNo(ownerRepayment.getOwnerUserNo());

        if (OwnerLoanRecordEnum.PayChannel.ORDER_DIRECT_PAY.getCode().equals(param.getPayChannel())) {
            // 订单支付
            NbBankOrderPayResultVO orderPayResultVO = bankService.orderDirectPay(ownerRepayment.getRepaymentNo(), "还款单",
                    ownerRepayment.getRepaymentBalance().intValue(), ownerBindCardRecord.getOpenAccountBankNumber(),
                    ownerBindCardRecord.getBankCardNumber(), ownerBindCardRecord.getAccountBankName());
            ownerRepayment.setRunningWaterOpenNo(orderPayResultVO.getTransSeqNo());
            ownerRepayment.setMerchantRunningWaterNo(orderPayResultVO.getMerSeqNo());

            bankTrade.setTradeType(BankTradeEnum.TradeType.ORDER_DIRECT_PAY.getCode());
        } else {
            // 订单转账支付
            NbBankOrderPayResultVO orderPayResultVO = bankService.orderTransferPay(ownerRepayment.getRepaymentBalance().intValue());
            ownerRepayment.setRunningWaterOpenNo(orderPayResultVO.getTransSeqNo());
            ownerRepayment.setMerchantRunningWaterNo(orderPayResultVO.getMerSeqNo());
            ownerRepayment.setRemittanceIdentificationCode(orderPayResultVO.getSignNo());
            ownerRepayment.setCloseOrderTime(orderPayResultVO.getCloseDtTm());
            bankTrade.setTradeType(BankTradeEnum.TradeType.ORDER_TRANSFER_PAY.getCode());
        }
        ownerRepayment.setStatus(OwnerRePaymentEnum.Status.PAYING.getCode());
        ownerRepayment.setPayChannel(param.getPayChannel());
        OwnerInfoFeignVO ownerInfo = ownerInfoService.getOwnerInfo(TokenUtil.getLoginUserInfo().getUserNo());
        ownerRepayment.setPayment(ownerBindCardRecord.getAccountBankName());
        ownerRepayment.setPaymentAccount(ownerInfo.getOwnerBankAccount());

        ownerRepayment.setOperateBy(TokenUtil.getLoginUserInfo().getUserName());
        ownerRepayment.setOperateTime(LocalDateTime.now());

        // 更新还款支付信息
        ownerRepaymentDao.updateRePay(ownerRepayment);

        bankTrade.setRelationNo(ownerRepayment.getRepaymentNo().toString());
        bankTrade.setOrderType(BankTradeEnum.OrderType.OWNER_REPAYMENT_RECORD.getCode());
        bankTrade.setAmount(ownerLoanRecord.getLoanBalance());
        bankTrade.setMerchantRunningWaterNo(ownerRepayment.getMerchantRunningWaterNo());
        bankTrade.setRunningWaterOpenNo(ownerRepayment.getRunningWaterOpenNo());
        bankTrade.setRemark("还款单");
        // 保存银行交易记录
        bankTradeDao.saveEntity(bankTrade);

    }

}

