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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.performance.config.loan.ClxPayeeConfig;
import com.clx.performance.config.loan.PaymentFromConfig;
import com.clx.performance.config.nbbank.NbBankConfig;
import com.clx.performance.dao.loan.OwnerRepaymentDao;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.loan.OwnerRePaymentEnum;
import com.clx.performance.extranal.user.impl.OwnerInfoServiceImpl;
import com.clx.performance.model.loan.OwnerRepayment;
import com.clx.performance.param.pc.loan.carrier.PageCarrierOwnerRepaymentParam;
import com.clx.performance.param.pc.loan.carrier.PageOwnerRepaymentOfOwner;
import com.clx.performance.param.pc.loan.owner.ExportPaymentApplicationFormParam;
import com.clx.performance.service.loan.OwnerRepaymentService;
import com.clx.performance.struct.loan.OwnerRepaymentStruct;
import com.clx.performance.vo.pc.loan.carrier.OwnerRepaymentVO;
import com.clx.performance.vo.pc.loan.owner.ExportOwnerRepaymentVO;
import com.clx.performance.vo.pc.loan.owner.OwnerCashierInfoVO;
import com.clx.performance.vo.pc.loan.owner.OwnerOrderPaymentDetailVO;
import com.clx.performance.vo.pc.loan.owner.OwnerTransferPaymentDetailVO;
import com.clx.user.vo.pc.owner.OwnerBindCardVO;
import com.msl.common.result.Result;
import com.msl.common.utils.DateUtils;
import com.msl.document.api.feign.ContractEvidenceFeign;
import com.msl.document.api.feign.ContractTemplateFeign;
import com.msl.document.api.param.GenerateContractParam;
import com.msl.document.api.vo.ContractEvidenceRecordVo;
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 java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

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

    private final OwnerRepaymentDao ownerRepaymentDao;
    private final OwnerRepaymentStruct ownerRepaymentStruct;
    private final ContractEvidenceFeign contractEvidenceFeign;
    private final ContractTemplateFeign contractTemplateFeign;
    private final PaymentFromConfig paymentFromConfig;
    private final OwnerInfoServiceImpl ownerInfoService;
    private final NbBankConfig nbBankConfig;

    @Override
    public IPage<OwnerRepaymentVO> pageOwnerRepayment(PageCarrierOwnerRepaymentParam param) {
        IPage<OwnerRepayment> page = ownerRepaymentDao.pageOwnerRepayment(param);
        List<OwnerRepaymentVO> records = ownerRepaymentStruct.convertList(page.getRecords());
        IPage<OwnerRepaymentVO> returnPage = new Page<>();
        returnPage.setPages(page.getPages());
        returnPage.setTotal(page.getTotal());
        returnPage.setRecords(records);
        return returnPage;
    }

    @Override
    public IPage<OwnerRepaymentVO> ownerRepaymentOverdueList() {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();
        PageCarrierOwnerRepaymentParam param = new PageCarrierOwnerRepaymentParam();
        param.setOwnerUserNo(String.valueOf(loginUserInfo.getUserNo()));
        List<Integer> inStatusList = new ArrayList<>();
        inStatusList.add(OwnerRePaymentEnum.Status.PAYING.getCode());
        inStatusList.add(OwnerRePaymentEnum.Status.PAY_WAIT.getCode());
        inStatusList.add(OwnerRePaymentEnum.Status.PAY_FAIL.getCode());
        param.setInStatusList(inStatusList);
        param.setBeOverdue(OwnerRePaymentEnum.BeOverdue.YES.getCode());

        IPage<OwnerRepayment> page = ownerRepaymentDao.pageOwnerRepayment(param);
        List<OwnerRepaymentVO> records = ownerRepaymentStruct.convertList(page.getRecords());
        IPage<OwnerRepaymentVO> returnPage = new Page<>();
        returnPage.setPages(page.getPages());
        returnPage.setTotal(page.getTotal());
        returnPage.setRecords(records);
        return returnPage;
    }


    @Override
    public IPage<OwnerRepaymentVO> pageOwnerRepaymentOfOwner(PageOwnerRepaymentOfOwner param) {
        return ownerRepaymentDao.pageByParam(param);
    }

    @Override
    public OwnerCashierInfoVO getCashierInfo(Integer id) {
        OwnerRepayment ownerRepayment = ownerRepaymentDao.getEntityByKey(id).orElseThrow(
                PerformanceResultEnum.DATA_NOT_FIND);
        OwnerCashierInfoVO vo = ownerRepaymentStruct.convertCashierInfo(ownerRepayment);

        OwnerBindCardVO bindCard = ownerInfoService.getOwnerBindCard(ownerRepayment.getOwnerUserNo());
        String ownerAccountBank = bindCard.getOwnerAccountBank();
        vo.setOrderPayWay(false);
        if(nbBankConfig.getOrderSupportBank().contains(ownerAccountBank)){
            vo.setOrderPayWay(true);
        }
        vo.setBankName(ownerAccountBank);
        vo.setPayAccount(bindCard.getOwnerBankAccount());
        return vo;
    }

    @Override
    public OwnerOrderPaymentDetailVO getOrderPaymentDetail(Integer id) {
        OwnerRepayment ownerRepayment = ownerRepaymentDao.getEntityByKey(id).orElseThrow(
                PerformanceResultEnum.DATA_NOT_FIND);
        OwnerOrderPaymentDetailVO vo = ownerRepaymentStruct.convertOrderPaymentDetail(ownerRepayment);
        //计算倒计时时间，下单时间 + 30天 为截止时间
        LocalDateTime endTime = ownerRepayment.getCreateTime().plusDays(30);
        vo.setFinalPaymentTime(DateUtils.formatDateTime(endTime).get());
        return vo;
    }

    @Override
    public OwnerTransferPaymentDetailVO getTransferPaymentDetail(Integer id) {
        OwnerRepayment ownerRepayment = ownerRepaymentDao.getEntityByKey(id).orElseThrow(
                PerformanceResultEnum.DATA_NOT_FIND);
        ClxPayeeConfig.PayeeConfig payeeMap = ClxPayeeConfig.getPayee(ClxPayeeConfig.XXH_ID);
        return OwnerTransferPaymentDetailVO.builder().payee(payeeMap.getName())
                .payeeAccount(payeeMap.getAccount()).payeeBank(payeeMap.getBank()).payeeBankNo(payeeMap.getBankNo())
                .repaymentBalance(ownerRepayment.getRepaymentBalance())
                .remittanceIdentificationCode(ownerRepayment.getRemittanceIdentificationCode())
                .status(ownerRepayment.getStatus()).finalPaymentTime(ownerRepayment.getCloseOrderTime()).build();
    }

    @Override
    public String savePaymentApplicationForm(ExportPaymentApplicationFormParam param) {
        OwnerRepayment ownerRepayment = ownerRepaymentDao.getEntityByKey(param.getId()).orElseThrow(
                PerformanceResultEnum.DATA_NOT_FIND);
        ExportOwnerRepaymentVO exportOwnerRepaymentVO = ownerRepaymentStruct.convert(ownerRepayment);
        Map<String,String> map = JSON.parseObject(JSON.toJSONString(exportOwnerRepaymentVO), new TypeReference<Map<String,String>>(){});
        // 创建合同
        GenerateContractParam feignParam = new GenerateContractParam();
        if(Objects.equals(OwnerRePaymentEnum.Channel.ORDER.getCode(),param.getPayWay())){
            feignParam.setTemplateNo(Long.valueOf(paymentFromConfig.getRepaymentOrderTemplateNo()));
        }else{
            feignParam.setTemplateNo(Long.valueOf(paymentFromConfig.getRepaymentTransferTemplateNo()));
        }

        feignParam.setParametersValueMap(map);
        Result<Long> longResult = contractTemplateFeign.generateContract(feignParam);
        Result<ContractEvidenceRecordVo> contractEvidenceDetail = contractEvidenceFeign.getContractEvidenceDetail(longResult.getData());
        return contractEvidenceDetail.getData().getFileUrl();
    }
}
