package com.ruoyi.loanpricing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.loanpricing.domain.dto.CorporateLoanPricingCreateDTO;
import com.ruoyi.loanpricing.domain.dto.PersonalLoanPricingCreateDTO;
import com.ruoyi.loanpricing.domain.entity.LoanPricingWorkflow;
import com.ruoyi.loanpricing.domain.entity.ModelCorpOutputFields;
import com.ruoyi.loanpricing.domain.entity.ModelRetailOutputFields;
import com.ruoyi.loanpricing.domain.vo.LoanPricingWorkflowListVO;
import com.ruoyi.loanpricing.domain.vo.LoanPricingWorkflowVO;
import com.ruoyi.loanpricing.mapper.LoanPricingWorkflowMapper;
import com.ruoyi.loanpricing.mapper.ModelCorpOutputFieldsMapper;
import com.ruoyi.loanpricing.mapper.ModelRetailOutputFieldsMapper;
import com.ruoyi.loanpricing.service.ILoanPricingWorkflowService;
import com.ruoyi.loanpricing.service.LoanPricingSensitiveDisplayService;
import com.ruoyi.loanpricing.service.LoanPricingModelService;
import com.ruoyi.loanpricing.service.SensitiveFieldCryptoService;
import com.ruoyi.loanpricing.util.LoanPricingConverter;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 利率定价流程Service业务层处理
 *
 * @author ruoyi
 * @date 2025-01-19
 */
@Service
public class LoanPricingWorkflowServiceImpl implements ILoanPricingWorkflowService
{
    @Resource
    private LoanPricingWorkflowMapper loanPricingWorkflowMapper;

    @Resource
    private LoanPricingModelService loanPricingModelService;

    @Resource
    private ModelRetailOutputFieldsMapper modelRetailOutputFieldsMapper;

    @Resource
    private ModelCorpOutputFieldsMapper modelCorpOutputFieldsMapper;

    @Resource
    private SensitiveFieldCryptoService sensitiveFieldCryptoService;

    @Resource
    private LoanPricingSensitiveDisplayService loanPricingSensitiveDisplayService;


    /**
     * 发起利率定价流程
     *
     * @param loanPricingWorkflow 利率定价流程信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public LoanPricingWorkflow createLoanPricing(LoanPricingWorkflow loanPricingWorkflow)
    {
        // 自动生成业务方流水号(时间戳)
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        String serialNum = sdf.format(new Date());
        loanPricingWorkflow.setSerialNum(serialNum);

        // 设置默认值
        if (!StringUtils.hasText(loanPricingWorkflow.getOrgCode()))
        {
            loanPricingWorkflow.setOrgCode("892000");
        }
        if (!StringUtils.hasText(loanPricingWorkflow.getRunType()))
        {
            loanPricingWorkflow.setRunType("1");
        }

        loanPricingWorkflow.setCustName(sensitiveFieldCryptoService.encrypt(loanPricingWorkflow.getCustName()));
        loanPricingWorkflow.setIdNum(sensitiveFieldCryptoService.encrypt(loanPricingWorkflow.getIdNum()));
        loanPricingWorkflowMapper.insert(loanPricingWorkflow);
        loanPricingModelService.invokeModelAsync(loanPricingWorkflow.getId());

        return loanPricingWorkflow;
    }

    /**
     * 发起个人客户利率定价流程
     *
     * @param dto 个人客户发起DTO
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoanPricingWorkflow createPersonalLoanPricing(PersonalLoanPricingCreateDTO dto) {
        LoanPricingWorkflow entity = LoanPricingConverter.toEntity(dto);
        return createLoanPricing(entity);
    }

    /**
     * 发起企业客户利率定价流程
     *
     * @param dto 企业客户发起DTO
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public LoanPricingWorkflow createCorporateLoanPricing(CorporateLoanPricingCreateDTO dto) {
        LoanPricingWorkflow entity = LoanPricingConverter.toEntity(dto);
        return createLoanPricing(entity);
    }

    /**
     * 查询利率定价流程列表
     *
     * @param loanPricingWorkflow 利率定价流程信息
     * @return 利率定价流程
     */
    @Override
    public List<LoanPricingWorkflow> selectLoanPricingList(LoanPricingWorkflow loanPricingWorkflow)
    {
        LambdaQueryWrapper<LoanPricingWorkflow> wrapper = buildQueryWrapper(loanPricingWorkflow);
        // 按更新时间倒序
        wrapper.orderByDesc(LoanPricingWorkflow::getUpdateTime);
        return loanPricingWorkflowMapper.selectList(wrapper);
    }

    /**
     * 分页查询利率定价流程列表
     *
     * @param page 分页参数
     * @param loanPricingWorkflow 利率定价流程信息
     * @return 利率定价流程
     */
    @Override
    public IPage<LoanPricingWorkflowListVO> selectLoanPricingPage(Page<LoanPricingWorkflowListVO> page, LoanPricingWorkflow loanPricingWorkflow)
    {
        IPage<LoanPricingWorkflowListVO> pageResult = loanPricingWorkflowMapper.selectWorkflowPageWithRates(page, loanPricingWorkflow);
        pageResult.getRecords().forEach(row -> row.setCustName(
                loanPricingSensitiveDisplayService.maskCustName(
                        sensitiveFieldCryptoService.decrypt(row.getCustName()))));
        return pageResult;
    }

    /**
     * 查询利率定价流程详情
     *
     * @param serialNum 业务方流水号
     * @return 利率定价流程
     */
    @Override
    public LoanPricingWorkflowVO selectLoanPricingBySerialNum(String serialNum)
    {
        LoanPricingWorkflowVO loanPricingWorkflowVO = new LoanPricingWorkflowVO();

        LambdaQueryWrapper<LoanPricingWorkflow> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LoanPricingWorkflow::getSerialNum, serialNum);
        LoanPricingWorkflow loanPricingWorkflow = loanPricingWorkflowMapper.selectOne(wrapper);
        String plainCustName = sensitiveFieldCryptoService.decrypt(loanPricingWorkflow.getCustName());
        String plainIdNum = sensitiveFieldCryptoService.decrypt(loanPricingWorkflow.getIdNum());
        loanPricingWorkflow.setCustName(loanPricingSensitiveDisplayService.maskCustName(plainCustName));
        loanPricingWorkflow.setIdNum(loanPricingSensitiveDisplayService.maskIdNum(plainIdNum));
        loanPricingWorkflowVO.setLoanPricingWorkflow(loanPricingWorkflow);

        if (Objects.nonNull(loanPricingWorkflow.getModelOutputId())){
            if (loanPricingWorkflow.getCustType().equals("个人")){
                ModelRetailOutputFields modelRetailOutputFields = modelRetailOutputFieldsMapper.selectById(loanPricingWorkflow.getModelOutputId());
                if (Objects.nonNull(modelRetailOutputFields))
                {
                    maskModelRetailOutputBasicInfo(modelRetailOutputFields);
                    loanPricingWorkflow.setLoanRate(modelRetailOutputFields.getFinalCalculateRate());
                }
                loanPricingWorkflowVO.setModelRetailOutputFields(modelRetailOutputFields);
            }
            if (loanPricingWorkflow.getCustType().equals("企业")){
                ModelCorpOutputFields modelCorpOutputFields = modelCorpOutputFieldsMapper.selectById(loanPricingWorkflow.getModelOutputId());
                if (Objects.nonNull(modelCorpOutputFields))
                {
                    maskModelCorpOutputBasicInfo(modelCorpOutputFields);
                    loanPricingWorkflow.setLoanRate(modelCorpOutputFields.getFinalCalculateRate());
                }
                loanPricingWorkflowVO.setModelCorpOutputFields(modelCorpOutputFields);
            }
        }


        return loanPricingWorkflowVO;
    }

    /**
     * 构建查询条件
     *
     * @param loanPricingWorkflow 利率定价流程信息
     * @return LambdaQueryWrapper
     */
    private LambdaQueryWrapper<LoanPricingWorkflow> buildQueryWrapper(LoanPricingWorkflow loanPricingWorkflow)
    {
        LambdaQueryWrapper<LoanPricingWorkflow> wrapper = new LambdaQueryWrapper<>();

        // 按创建者筛选
        if (StringUtils.hasText(loanPricingWorkflow.getCreateBy()))
        {
            wrapper.like(LoanPricingWorkflow::getCreateBy, loanPricingWorkflow.getCreateBy());
        }

        // 按客户内码模糊查询
        if (StringUtils.hasText(loanPricingWorkflow.getCustIsn()))
        {
            wrapper.like(LoanPricingWorkflow::getCustIsn, loanPricingWorkflow.getCustIsn());
        }

        // 按机构号筛选
        if (StringUtils.hasText(loanPricingWorkflow.getOrgCode()))
        {
            wrapper.like(LoanPricingWorkflow::getOrgCode, loanPricingWorkflow.getOrgCode());
        }

        return wrapper;
    }

    private void maskModelRetailOutputBasicInfo(ModelRetailOutputFields modelRetailOutputFields)
    {
        modelRetailOutputFields.setCustName(
                loanPricingSensitiveDisplayService.maskCustName(modelRetailOutputFields.getCustName()));
        modelRetailOutputFields.setIdNum(
                loanPricingSensitiveDisplayService.maskIdNum(modelRetailOutputFields.getIdNum()));
    }

    private void maskModelCorpOutputBasicInfo(ModelCorpOutputFields modelCorpOutputFields)
    {
        modelCorpOutputFields.setCustName(
                loanPricingSensitiveDisplayService.maskCustName(modelCorpOutputFields.getCustName()));
        modelCorpOutputFields.setIdNum(
                loanPricingSensitiveDisplayService.maskIdNum(modelCorpOutputFields.getIdNum()));
    }

    /**
     * 设定执行利率
     *
     * @param serialNum   业务方流水号
     * @param executeRate 执行利率
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setExecuteRate(String serialNum, String executeRate) {
        LambdaQueryWrapper<LoanPricingWorkflow> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(LoanPricingWorkflow::getSerialNum, serialNum);
        LoanPricingWorkflow workflow = loanPricingWorkflowMapper.selectOne(wrapper);

        if (workflow == null) {
            return false;
        }

        workflow.setExecuteRate(executeRate);
        int result = loanPricingWorkflowMapper.updateById(workflow);
        return result > 0;
    }
}
