package com.yd.csf.api.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.base.feign.client.bank.ApiBankFeignClient;
import com.yd.base.feign.client.exchangerate.ApiExchangeRateFeignClient;
import com.yd.base.feign.request.bank.ApiBankListRequest;
import com.yd.base.feign.request.exchangerate.ApiExchangeRateConvertRequest;
import com.yd.base.feign.response.bank.ApiBankDetailResponse;
import com.yd.base.feign.response.exchangerate.ApiExchangeRateConvertResponse;
import com.yd.common.enums.CommonEnum;
import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.api.service.ApiPremiumReconciliationService;
import com.yd.csf.api.service.ApiPremiumRemittanceService;
import com.yd.csf.feign.dto.premiumreconciliation.ApiPremiumReconciliationDto;
import com.yd.csf.feign.dto.premiumremittance.ApiPremiumRemittanceDto;
import com.yd.csf.feign.enums.ReconciliationStatusEnum;
import com.yd.csf.feign.request.premiumreconciliation.ApiCalculateRemainingUnpaidAmountRequest;
import com.yd.csf.feign.request.premiumreconciliation.ApiPremiumReconciliationAddRequest;
import com.yd.csf.feign.request.premiumreconciliation.ApiPremiumReconciliationPageRequest;
import com.yd.csf.feign.request.premiumreconciliation.ApiPremiumReconciliationResultEditRequest;
import com.yd.csf.feign.response.premiumreconciliation.ApiCalculateRemainingUnpaidAmountResponse;
import com.yd.csf.feign.response.premiumreconciliation.ApiPremiumReconciliationDetailResponse;
import com.yd.csf.feign.response.premiumreconciliation.ApiPremiumReconciliationPageResponse;
import com.yd.csf.feign.response.team.ApiTeamPageResponse;
import com.yd.csf.service.dto.PremiumReconciliationDto;
import com.yd.csf.service.model.Policy;
import com.yd.csf.service.model.PolicyFollow;
import com.yd.csf.service.model.PremiumReconciliation;
import com.yd.csf.service.service.IPremiumReconciliationService;
import com.yd.csf.service.service.PolicyFollowService;
import com.yd.csf.service.service.PolicyService;
import com.yd.user.feign.client.sysdict.ApiSysDictFeignClient;
import com.yd.user.feign.request.sysdict.GetDictTypeListRequest;
import com.yd.user.feign.response.sysdict.GetDictItemListByDictTypeResponse;
import com.yd.user.feign.response.sysdict.GetDictTypeListResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@Service
public class ApiPremiumReconciliationServiceImpl implements ApiPremiumReconciliationService {

    @Autowired
    private PolicyService policyService;

    @Autowired
    private IPremiumReconciliationService iPremiumReconciliationService;

    @Autowired
    private ApiPremiumRemittanceService apiPremiumRemittanceService;

    @Autowired
    private ApiExchangeRateFeignClient apiExchangeRateFeignClient;

    @Autowired
    private PolicyFollowService policyFollowService;

    @Autowired
    private ApiSysDictFeignClient apiSysDictFeignClient;

    @Autowired
    private ApiBankFeignClient apiBankFeignClient;

    /**
     * 分页列表查询-保费对账记录信息
     * @param request
     * @return
     */
    @Override
    public Result<IPage<ApiPremiumReconciliationPageResponse>> page(ApiPremiumReconciliationPageRequest request) {
        Page<ApiPremiumReconciliationPageResponse> page = new Page<>(request.getPageNo(), request.getPageSize());
        IPage<ApiPremiumReconciliationPageResponse> iPage = iPremiumReconciliationService.page(page, request);

        // 获取缴费方式字典数据
        Map<String, String> paymentMethodDictMap = getPaymentMethodDict();

        // 获取所有银行ID，准备翻译银行名称
        Set<String> bankBizIdSet = new HashSet<>();

        // 收集所有银行ID并翻译缴费方式
        if (iPage != null && !CollectionUtils.isEmpty(iPage.getRecords())) {
            for (ApiPremiumReconciliationPageResponse item : iPage.getRecords()) {
                // 翻译缴费方式
                if (StringUtils.isNotBlank(item.getPaymentMethod())) {
                    String translated = translatePaymentMethod(item.getPaymentMethod(), paymentMethodDictMap);
                    item.setPaymentMethod(translated);
                }

                // 收集银行ID（payingBank字段）
                if (StringUtils.isNotBlank(item.getPayingBank())) {
                    // 分割多个银行ID（用分号分隔）
                    String[] bankIds = item.getPayingBank().split(";");
                    for (String bankId : bankIds) {
                        if (StringUtils.isNotBlank(bankId.trim())) {
                            bankBizIdSet.add(bankId.trim());
                        }
                    }
                }
            }
        }

        // 翻译银行名称
        if (!bankBizIdSet.isEmpty()) {
            Map<String, String> bankNameMap = getBankNames(bankBizIdSet);

            // 翻译银行名称字段
            for (ApiPremiumReconciliationPageResponse item : iPage.getRecords()) {
                if (StringUtils.isNotBlank(item.getPayingBank())) {
                    String translated = translateBankNames(item.getPayingBank(), bankNameMap);
                    item.setPayingBank(translated);
                }
            }
        }

        return Result.success(iPage);
    }

    /**
     * 获取缴费方式字典数据
     */
    private Map<String, String> getPaymentMethodDict() {
        Map<String, String> dictMap = new HashMap<>();
        try {
            GetDictTypeListRequest dictRequest = new GetDictTypeListRequest();
            dictRequest.setTypeList(Collections.singletonList("csf_ap_first_issue"));
            List<GetDictTypeListResponse> dictTypeResponses = apiSysDictFeignClient.getByDictTypeList(dictRequest).getData();

            if (dictTypeResponses != null && !dictTypeResponses.isEmpty()) {
                for (GetDictTypeListResponse dictTypeResponse : dictTypeResponses) {
                    if ("csf_ap_first_issue".equals(dictTypeResponse.getDictType())
                            && dictTypeResponse.getDictItemList() != null) {
                        for (GetDictItemListByDictTypeResponse dictItem : dictTypeResponse.getDictItemList()) {
                            dictMap.put(dictItem.getItemValue(), dictItem.getItemLabel());
                        }
                        break;
                    }
                }
            }
        } catch (Exception e) {
            log.error("获取缴费方式字典数据失败", e);
        }
        return dictMap;
    }

    /**
     * 获取银行名称映射
     */
    private Map<String, String> getBankNames(Set<String> bankBizIdSet) {
        Map<String, String> bankNameMap = new HashMap<>();
        try {
            ApiBankListRequest bankRequest = new ApiBankListRequest();
            bankRequest.setBankBizIdList(new ArrayList<>(bankBizIdSet));
            Result<List<ApiBankDetailResponse>> bankResult = apiBankFeignClient.list(bankRequest);

            if (bankResult != null && bankResult.getCode() == 200 && !CollectionUtils.isEmpty(bankResult.getData())) {
                for (ApiBankDetailResponse bankDetail : bankResult.getData()) {
                    // 优先使用银行简称，如果没有则使用银行全称
                    String bankName = StringUtils.isNotBlank(bankDetail.getBankShortName())
                            ? bankDetail.getBankShortName()
                            : bankDetail.getBankName();
                    bankNameMap.put(bankDetail.getBankBizId(), bankName);
                }
            }
        } catch (Exception e) {
            log.error("获取银行名称失败", e);
        }
        return bankNameMap;
    }

    /**
     * 翻译缴费方式
     * 处理多个缴费方式（用分号分隔）的情况
     */
    private String translatePaymentMethod(String paymentMethod, Map<String, String> dictMap) {
        if (StringUtils.isBlank(paymentMethod)) {
            return paymentMethod;
        }

        String[] methods = paymentMethod.split(";");
        StringBuilder translated = new StringBuilder();

        for (int i = 0; i < methods.length; i++) {
            String method = methods[i].trim();
            String label = dictMap.get(method);

            if (label != null) {
                translated.append(label);
            } else {
                translated.append(method); // 如果找不到对应的字典项，保留原值
            }

            if (i < methods.length - 1) {
                translated.append(";");
            }
        }

        return translated.toString();
    }

    /**
     * 翻译银行名称
     * 处理多个银行（用分号分隔）的情况
     */
    private String translateBankNames(String payingBank, Map<String, String> bankNameMap) {
        if (StringUtils.isBlank(payingBank)) {
            return payingBank;
        }

        String[] bankIds = payingBank.split(";");
        StringBuilder translated = new StringBuilder();

        for (int i = 0; i < bankIds.length; i++) {
            String bankId = bankIds[i].trim();
            String bankName = bankNameMap.get(bankId);

            if (bankName != null) {
                translated.append(bankName);
            } else {
                translated.append(bankId); // 如果找不到对应的银行，保留原ID
            }

            if (i < bankIds.length - 1) {
                translated.append(";");
            }
        }

        return translated.toString();
    }

    /**
     * 添加-保费对账记录信息
     * @param request
     * @return
     */
    @Override
    public Result add(ApiPremiumReconciliationAddRequest request) {
        //根据当前Policy保单信息里面的生效日期、付款频率、缴费宽限期，校验当天是否在缴费期内，不在缴费期内不能保费对账 TODO 校验待定
        //保费对账信息
        ApiPremiumReconciliationDto apiPremiumReconciliationDto = request.getApiPremiumReconciliationDto();
        //校验-保单所有期数的保费对账是否对账完成（全部对账完成就不能新增录入对账信息了）
//        Result<Boolean> result = checkReconciliationComplete(apiPremiumReconciliationDto.getPolicyNo());
//        if (!result.getData()) {
//            throw new BusinessException(result.getMsg());
//        }
        //校验保单信息是否存在
        Policy policy = policyService.queryOne(apiPremiumReconciliationDto.getPolicyNo());
        if (Objects.isNull(policy)) {
            throw new BusinessException("保单信息不存在");
        }
        PremiumReconciliation premiumReconciliation = new PremiumReconciliation();
        //计算当前期数
        String currentIssueNumber = calculateCurrentIssueNumber(policy.getPolicyNo(),Integer.parseInt(policy.getPaymentTerm().toString()));
        //根据计算的当前期数和保单号查询最新的记录，如果无记录那么新增的对账记录的待付金额为保单保费的金额，否则为最新记录的待付金额。
        PremiumReconciliation newDto = iPremiumReconciliationService.queryLatestOneByPolicyNo(policy.getPolicyNo(),currentIssueNumber);
        if (Objects.isNull(newDto)) {
            //无记录那么新增的对账记录的待付金额为保单保费的金额
            premiumReconciliation.setRemainingUnpaidCurrency(policy.getCurrency());
            premiumReconciliation.setRemainingUnpaidAmount(policy.getPaymentPremium());
        }else {
            //否则为最新记录的待付金额。
            premiumReconciliation.setRemainingUnpaidCurrency(newDto.getRemainingUnpaidCurrency());
            premiumReconciliation.setRemainingUnpaidAmount(newDto.getRemainingUnpaidAmount());
        }
        //申请人
        premiumReconciliation.setApplicant(apiPremiumReconciliationDto.getApplicant());
        //当前期数
        premiumReconciliation.setCurrentIssueNumber(currentIssueNumber);
        //保单受保人（被保人）
        premiumReconciliation.setInsured(policy.getInsured());
        //保险公司名称
        premiumReconciliation.setInsuranceCompany(policy.getInsuranceCompany());
        //保单号
        premiumReconciliation.setPolicyNo(policy.getPolicyNo());
        premiumReconciliation.setReconciliationType(apiPremiumReconciliationDto.getReconciliationType());
        //保费对账记录表唯一业务ID
        premiumReconciliation.setPremiumReconciliationBizId(RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_PREMIUM_RECONCILIATION.getCode()));
        //对账状态 - 保司对账中
        premiumReconciliation.setReconciliationStatus(ReconciliationStatusEnum.BS_DZZ.getItemValue());
        iPremiumReconciliationService.saveOrUpdate(premiumReconciliation);

        //添加-保费对账汇款记录列表
        apiPremiumRemittanceService.addPremiumRemittanceList(request.getApiPremiumRemittanceDtoList(),
                premiumReconciliation.getPremiumReconciliationBizId());

        return Result.success();
    }

    /**
     * 计算当前期数
     * @param policyNo
     * @return
     */
    public String calculateCurrentIssueNumber(String policyNo,Integer paymentTerm) {
        //保单号查询对账记录无数据，说明第一期。有数据：1、最新的记录的待付金额大于0，当前期数为最新的记录期数。2、最新的记录的待付金额小于等于0，当前期数 = 最新的记录期数 + 1 <= 保单的供款年期
        //保单号查询对账记录无数据，说明第一期
        //根据保单号查询最新对账记录
        PremiumReconciliation premiumReconciliation = iPremiumReconciliationService.queryLatestOneByPolicyNo(policyNo,"");
        if (Objects.isNull(premiumReconciliation)) {
            return "1";
        }
        if (ReconciliationStatusEnum.BS_DZZ.getItemValue().equals(premiumReconciliation.getReconciliationStatus())) {
            //当前保单号的记录的对账状态为对账中，请先对账完成再发起新的对账
            throw new BusinessException("当前保单号的最新的对账记录的对账状态为对账中，请先设置认定结果，再发起新的对账");
        }
        //有数据，最新的记录的待付金额大于0，当前期数为最新的记录期数
        if (premiumReconciliation.getRemainingUnpaidAmount().compareTo(BigDecimal.ZERO) > 0) {
            return premiumReconciliation.getCurrentIssueNumber();
        }
        //最新的记录的待付金额小于等于0，当前期数 = 最新的记录期数 + 1 <= 保单的供款年期
        if (premiumReconciliation.getRemainingUnpaidAmount().compareTo(BigDecimal.ZERO) <= 0) {
            //最新的记录期数 + 1
            Integer thisQs = Integer.parseInt(premiumReconciliation.getCurrentIssueNumber()) + 1;
            if (thisQs > paymentTerm) {
                //最新的记录期数 + 1 > 保单的供款年期，提示
                throw new BusinessException("当前保单保费所有期数已经全部对账完成，不能对账了");
            }
            return thisQs.toString();
        }
        return "1";
    }

    /**
     * 编辑-单个保费对账记录信息
     * @param request
     * @return
     */
    @Override
    public Result edit(ApiPremiumReconciliationDto request) {
        if (StringUtils.isBlank(request.getPremiumReconciliationBizId())) {
            throw new BusinessException("保费对账记录表唯一业务ID不能为空");
        }
        //校验保费对账记录信息是否存在
        Result<PremiumReconciliation> result = checkPremiumReconciliationIsExist(request.getPremiumReconciliationBizId());
        PremiumReconciliation premiumReconciliation = result.getData();
        BeanUtils.copyProperties(request,premiumReconciliation);
        iPremiumReconciliationService.saveOrUpdate(premiumReconciliation);
        return Result.success();
    }

    /**
     * 详情-保费对账记录信息
     * @param premiumReconciliationBizId 保费对账记录表唯一业务ID
     * @return
     */
    @Override
    public Result<ApiPremiumReconciliationDetailResponse> detail(String premiumReconciliationBizId) {
        ApiPremiumReconciliationDetailResponse response = new ApiPremiumReconciliationDetailResponse();
        //校验保费对账记录信息是否存在
        Result<PremiumReconciliation> result = checkPremiumReconciliationIsExist(premiumReconciliationBizId);
        PremiumReconciliation premiumReconciliation = result.getData();
        ApiPremiumReconciliationDto apiPremiumReconciliationDto = new ApiPremiumReconciliationDto();
        BeanUtils.copyProperties(premiumReconciliation,apiPremiumReconciliationDto);
        response.setApiPremiumReconciliationDto(apiPremiumReconciliationDto);
        //保费对账-汇款记录列表
        List<ApiPremiumRemittanceDto> apiPremiumRemittanceDtoList = apiPremiumRemittanceService.apiPremiumRemittanceDtoList(premiumReconciliationBizId);
        response.setApiPremiumRemittanceDtoList(apiPremiumRemittanceDtoList);
        return Result.success(response);
    }

    /**
     * 计算待付金额-保费对账记录信息
     * @param request
     * @return
     */
    @Override
    public Result<ApiCalculateRemainingUnpaidAmountResponse> calculateRemainingUnpaidAmount(ApiCalculateRemainingUnpaidAmountRequest request) {
        //校验保费对账记录信息是否存在
        Result<PremiumReconciliation> result = checkPremiumReconciliationIsExist(request.getPremiumReconciliationBizId());
        PremiumReconciliation premiumReconciliation = result.getData();

        //查询保单信息
        Policy policy = policyService.queryOne(premiumReconciliation.getPolicyNo());
        if (Objects.isNull(policy)) {
            throw new BusinessException("保单信息不存在");
        }

        //获取保单币种
        String policyCurrency = policy.getCurrency();
        if (StringUtils.isBlank(policyCurrency)) {
            throw new BusinessException("保单币种不能为空");
        }

        //验证保单币种是否支持 - 通过Feign客户端调用
        Result<Boolean> currencySupportedResult = apiExchangeRateFeignClient.isCurrencySupportedResult(policyCurrency);
        if (currencySupportedResult.getCode() != 200 || Boolean.FALSE.equals(currencySupportedResult.getData())) {
            throw new BusinessException("保单币种不支持: " + policyCurrency);
        }

        //将当次保司认定金额转换为保单币种的金额
        String recognizedCurrency = request.getRecognizedCurrency();
        if (StringUtils.isBlank(recognizedCurrency)) {
            throw new BusinessException("当次保司认定币种不能为空");
        }

        //验证认定币种是否支持 - 通过Feign客户端调用
        Result<Boolean> recognizedCurrencySupportedResult = apiExchangeRateFeignClient.isCurrencySupportedResult(recognizedCurrency);
        if (recognizedCurrencySupportedResult.getCode() != 200 || Boolean.FALSE.equals(recognizedCurrencySupportedResult.getData())) {
            throw new BusinessException("认定币种不支持: " + recognizedCurrency);
        }

        //转换当次保司认定金额到保单币种的金额 - 通过Feign客户端调用
        BigDecimal currentRecognizedAmount = request.getRecognizedAmount();
        BigDecimal currentRecognizedAmountInPolicyCurrency;

        if (recognizedCurrency.equalsIgnoreCase(policyCurrency)) {
            // 币种相同，直接使用原金额
            currentRecognizedAmountInPolicyCurrency = currentRecognizedAmount;
        } else {
            // 币种不相同，调用汇率服务进行转换
            ApiExchangeRateConvertRequest convertRequest = new ApiExchangeRateConvertRequest();
            //被转换金额
            convertRequest.setAmount(currentRecognizedAmount);
            //被转换币种
            convertRequest.setFromCurrency(recognizedCurrency);
            //转换币种
            convertRequest.setToCurrency(policyCurrency);
            // 可以根据需要设置交易日期或汇率日期，这里null查询最新汇率日期的汇率转换
            convertRequest.setTransactionDate(null);
//            convertRequest.setTransactionDate(request.getTransactionDate());

            Result<ApiExchangeRateConvertResponse> convertResult = apiExchangeRateFeignClient.convert(convertRequest);
            if (convertResult.getCode() != 200) {
                throw new BusinessException("币种转换失败: " + convertResult.getMsg());
            }

            currentRecognizedAmountInPolicyCurrency = convertResult.getData().getConvertedAmount();
        }

        //根据当前期数和保单号，查询非当前保费对账记录的保司认定金额之和
        List<PremiumReconciliation> premiumReconciliationList = iPremiumReconciliationService.queryList(PremiumReconciliationDto.builder()
                .premiumReconciliationBizId(request.getPremiumReconciliationBizId())
                .currentIssueNumber(premiumReconciliation.getCurrentIssueNumber())
                .isExcludeMy(true)
                .build());

        //计算非当前保费对账记录的保司认定金额之和（转换为保单币种）
        BigDecimal otherRecognizedAmountSumInPolicyCurrency = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(premiumReconciliationList)) {
            for (PremiumReconciliation pr : premiumReconciliationList) {
                if (pr.getRecognizedAmount() != null && StringUtils.isNotBlank(pr.getRecognizedCurrency())) {
                    //将每条记录的认定金额转换为保单币种
                    BigDecimal convertedAmount;

                    if (pr.getRecognizedCurrency().equalsIgnoreCase(policyCurrency)) {
                        // 币种相同，直接使用
                        convertedAmount = pr.getRecognizedAmount();
                    } else {
                        // 调用汇率服务进行转换
                        ApiExchangeRateConvertRequest prConvertRequest = new ApiExchangeRateConvertRequest();
                        prConvertRequest.setAmount(pr.getRecognizedAmount());
                        prConvertRequest.setFromCurrency(pr.getRecognizedCurrency());
                        prConvertRequest.setToCurrency(policyCurrency);

                        Result<ApiExchangeRateConvertResponse> prConvertResult = apiExchangeRateFeignClient.convert(prConvertRequest);
                        if (prConvertResult.getCode() != 200) {
                            log.warn("保费对账记录币种转换失败，记录ID: {}, 原因: {}",
                                    pr.getPremiumReconciliationBizId(), prConvertResult.getMsg());
                            continue; // 跳过转换失败的记录
                        }

                        convertedAmount = prConvertResult.getData().getConvertedAmount();
                    }

                    otherRecognizedAmountSumInPolicyCurrency = otherRecognizedAmountSumInPolicyCurrency.add(convertedAmount);
                }
            }
        }

        //计算总认定金额（保单币种）
        BigDecimal totalRecognizedAmountInPolicyCurrency =
                otherRecognizedAmountSumInPolicyCurrency.add(currentRecognizedAmountInPolicyCurrency);

        //获取期交保费（如果为空则设为0）
        BigDecimal paymentPremium = policy.getPaymentPremium() != null ?
                policy.getPaymentPremium() : BigDecimal.ZERO;

        //获取保单征费（转换为BigDecimal）
        BigDecimal policyLevy = BigDecimal.ZERO;
        if (StringUtils.isNotBlank(policy.getPolicyLevy())) {
            try {
                // 注意：保单征费的币种应该与保单币种一致，但这里可以再次确认
                String policyLevyStr = policy.getPolicyLevy().trim();
                // 如果保单征费包含币种信息，需要解析，这里假设是纯数字字符串
                policyLevy = new BigDecimal(policyLevyStr);
            } catch (NumberFormatException e) {
                log.error("保单征费格式错误，policyLevy: {}", policy.getPolicyLevy());
                throw new BusinessException("保单征费格式错误，无法计算");
            }
        }

        //计算总额和剩余待付金额（均为保单币种）
        BigDecimal totalPremium = paymentPremium.add(policyLevy);
        BigDecimal remainingUnpaidAmount = totalPremium.subtract(totalRecognizedAmountInPolicyCurrency);

        //如果剩余待付金额为负数，说明已超额支付，可以设为0或负数，根据业务需求
        // 如果要求不能为负数，则取最大值
        // remainingUnpaidAmount = remainingUnpaidAmount.max(BigDecimal.ZERO);

        // 设置精度，保留2位小数，银行家舍入法
        remainingUnpaidAmount = remainingUnpaidAmount.setScale(2, RoundingMode.HALF_EVEN);

        //构建响应对象
        ApiCalculateRemainingUnpaidAmountResponse response = new ApiCalculateRemainingUnpaidAmountResponse();
        response.setRemainingUnpaidAmount(remainingUnpaidAmount);
        response.setRemainingUnpaidCurrency(policyCurrency);

        return Result.success(response);
    }

    /**
     * 设置认定结果-保费对账记录信息
     * @param request
     * @return
     */
    @Override
    public Result editResult(ApiPremiumReconciliationResultEditRequest request) {
        //校验保费对账记录信息是否存在
        Result<PremiumReconciliation> result = checkPremiumReconciliationIsExist(request.getPremiumReconciliationBizId());
        PremiumReconciliation premiumReconciliation = result.getData();
        BeanUtils.copyProperties(request,premiumReconciliation);
        //对账状态->保司对账成功
        premiumReconciliation.setReconciliationStatus(ReconciliationStatusEnum.BS_DZ_CG.getItemValue());
        //更新保费对账记录信息
        iPremiumReconciliationService.saveOrUpdate(premiumReconciliation);

        //校验当期剩余待付金额小于等于0并且当前期数是第一期首期，才会去更新保单生效日期和保单状态
        if (premiumReconciliation.getCurrentIssueNumber().equals("1")) {
            //当前期数是第一期首期
            if (request.getRemainingUnpaidAmount().compareTo(BigDecimal.ZERO) <= 0) {
                //校验生效日期、核保日期必填
                if (Objects.isNull(request.getEffectiveDate())) {
                    throw new BusinessException("生效日期不能为空");
                }
                if (Objects.isNull(request.getUnderwritingDate())) {
                    throw new BusinessException("核保日期不能为空");
                }
                //更新新单和保单状态为生效中，更新生效日期和核保日期
                //更新新单跟进：新单状态——>生效、生效日期、核保日期
                PolicyFollow policyFollow = policyFollowService.queryOneByPolicyNo(premiumReconciliation.getPolicyNo());
                if (!Objects.isNull(policyFollow)) {
                    //生效日期
                    policyFollow.setEffectiveDate(request.getEffectiveDate());
                    //核保日期
                    policyFollow.setUnderwritingDate(request.getUnderwritingDate());
                    //新单跟进状态——>生效
                    policyFollow.setStatus("TAKE_EFFECT");
                    policyFollowService.saveOrUpdate(policyFollow);
                }
                //更新保单信息：保单状态——>生效、生效日期、核保日期
                Policy policy = policyService.queryOne(premiumReconciliation.getPolicyNo());
                if (!Objects.isNull(policy)) {
                    //生效日期
                    policy.setEffectiveDate(request.getEffectiveDate());
                    //核保日期
                    policy.setUnderwritingDate(request.getUnderwritingDate());
                    //保单状态——>生效
                    if (StringUtils.isNotBlank(request.getStatus())) {
                        policy.setStatus(request.getStatus());
                    }else {
                        policy.setStatus("TAKE_EFFECT");
                    }
                    policyService.saveOrUpdate(policy);
                }
            }else {
                //大于0，只更新新单跟进：新单状态——>保费对账成功，核保中
                PolicyFollow policyFollow = policyFollowService.queryOneByPolicyNo(premiumReconciliation.getPolicyNo());
                if (!Objects.isNull(policyFollow)) {
                    //新单跟进状态——>保费对账成功，核保中
                    policyFollow.setStatus("UNDERWRITING_PROGRESS");
                    policyFollowService.saveOrUpdate(policyFollow);
                }
            }
        }
        return Result.success();
    }

    /**
     * 校验-保单所有期数的保费对账是否对账完成（全部对账完成就不能新增录入对账信息了）
     * @param policyNo
     * @return
     */
    @Override
    public Result<Boolean> checkReconciliationComplete(String policyNo) {
        //查询保单信息
        Policy policy = policyService.queryOne(policyNo);
        if (Objects.isNull(policy)) {
            throw new BusinessException("保单信息不存在");
        }
        //获取保单供款年期
        String paymentTerm = String.valueOf(policy.getPaymentTerm());
        //根据保单号查询最新对账记录
        PremiumReconciliation premiumReconciliation = iPremiumReconciliationService.queryLatestOneByPolicyNo(policyNo,"");
        if (Objects.isNull(premiumReconciliation)) {
            //无数据，说明还没有对账记录，可以对账。
            return Result.success(true);
        }
        if (ReconciliationStatusEnum.BS_DZZ.getItemValue().equals(premiumReconciliation.getReconciliationStatus())) {
            //当前保单号的记录的对账状态为对账中，请先对账完成再发起新的对账
            return Result.success(false,"当前保单号的最新的对账记录的对账状态为对账中，请先设置认定结果，再发起新的对账");
        }
        //有数据
        //校验最新对账记录的待付金额是否小于等于0并且当前期数等于保单的供款年期，如果是说明对账所有期数已经全部完成不能对账了。
        if (premiumReconciliation.getRemainingUnpaidAmount().compareTo(BigDecimal.ZERO) <= 0
                && premiumReconciliation.getCurrentIssueNumber().equals(paymentTerm)) {
            return Result.success(false,"当前保单保费所有期数已经全部对账完成，不能对账了");
        }
        return Result.success(true);
    }

    /**
     * 校验保费对账记录信息是否存在
     * @param premiumReconciliationBizId
     * @return
     */
    @Override
    public Result<PremiumReconciliation> checkPremiumReconciliationIsExist(String premiumReconciliationBizId) {
        PremiumReconciliation premiumReconciliation = iPremiumReconciliationService.queryOne(premiumReconciliationBizId);
        if (Objects.isNull(premiumReconciliation)) {
            //数据不存在
            throw new BusinessException("保费对账记录信息不存在");
        }
        return Result.success(premiumReconciliation);
    }

}
