package com.yd.csf.service.service.impl;
import java.util.Date;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yd.auth.core.dto.AuthUserDto;
import com.yd.auth.core.utils.SecurityUtil;
import com.yd.common.enums.CommonEnum;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.csf.service.common.ErrorCode;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.enums.PolicyFollowStatusEnum;
import com.yd.csf.service.model.*;
import com.yd.csf.service.service.*;
import com.yd.csf.service.dao.PolicyFollowMapper;
import com.yd.csf.service.utils.AsyncQueryUtil;
import com.yd.csf.service.utils.GSONUtil;
import com.yd.csf.service.vo.PolicyFollowVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
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.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Zhang Jianan
* @description 针对表【policy_follow(新单跟进表)】的数据库操作Service实现
* @createDate 2025-09-16 18:18:06
*/
@Service
@Slf4j
public class PolicyFollowServiceImpl extends ServiceImpl<PolicyFollowMapper, PolicyFollow>
    implements PolicyFollowService{

    @Resource
    private PolicyBrokerService policyBrokerService;
    @Resource
    private PolicyService policyService;
    @Resource
    private PolicyFollowService policyFollowService;
    @Resource
    private PolicyFollowRecordService policyFollowRecordService;
    @Resource
    private PolicyFollowFileService policyFollowFileService;
    @Resource
    private AsyncQueryUtil asyncQueryUtil;
    @Resource
    private PolicyPolicyholderService policyPolicyholderService;
    @Resource
    private PolicyInsurantService policyInsurantService;
    @Resource
    private PolicyBeneficiaryService policyBeneficiaryService;
    @Resource
    private PolicySecondHolderService policySecondHolderService;
    @Resource
    private PolicyAdditionalService policyAdditionalService;
    @Resource
    private IExpectedFortuneService expectedFortuneService;
    @Autowired
    private CommissionExpectedService commissionExpectedService;

    @Override
    public PolicyFollow getByPolicyBizId(String policyBizId) {
        return this.getOne(new QueryWrapper<PolicyFollow>().eq("policy_biz_id", policyBizId));
    }

    @Override
    public QueryWrapper<PolicyFollow> getQueryWrapper(PolicyFollowQueryRequest policyFollowQueryRequest) {
        QueryWrapper<PolicyFollow> queryWrapper = new QueryWrapper<>();
        if (policyFollowQueryRequest == null) {
            return queryWrapper;
        }

        String policyNo = policyFollowQueryRequest.getPolicyNo();
        String status = policyFollowQueryRequest.getStatus();
        String appointmentNo = policyFollowQueryRequest.getAppointmentNo();
        Date signDateStart = policyFollowQueryRequest.getSignDateStart();
        Date signDateEnd = policyFollowQueryRequest.getSignDateEnd();
        Date latestPaymentDate = policyFollowQueryRequest.getLatestPaymentDate();
        List<String> insuranceCompanyBizIdList = policyFollowQueryRequest.getInsuranceCompanyBizIdList();
        List<String> productLaunchBizIdList = policyFollowQueryRequest.getProductLaunchBizIdList();
        String issueNumber = policyFollowQueryRequest.getIssueNumber();

        queryWrapper.eq(ObjectUtils.isNotEmpty(policyNo), "policy_no", policyNo);
        queryWrapper.eq(ObjectUtils.isNotEmpty(status), "status", status);
        queryWrapper.eq(ObjectUtils.isNotEmpty(appointmentNo), "appointment_no", appointmentNo);
        queryWrapper.ge(ObjectUtils.isNotEmpty(signDateStart), "sign_date", signDateStart);
        queryWrapper.le(ObjectUtils.isNotEmpty(signDateEnd), "sign_date", signDateEnd);
        queryWrapper.ge(ObjectUtils.isNotEmpty(latestPaymentDate), "latest_payment_date", latestPaymentDate);

        if (CollectionUtils.isNotEmpty(insuranceCompanyBizIdList)) {
            queryWrapper.in("insurance_company_biz_id", insuranceCompanyBizIdList);
        }
        if (CollectionUtils.isNotEmpty(productLaunchBizIdList)) {
            queryWrapper.in("product_launch_biz_id", productLaunchBizIdList);
        }
        queryWrapper.eq(ObjectUtils.isNotEmpty(issueNumber), "issue_number", issueNumber);
        // 排序：按创建时间倒序
        queryWrapper.orderByDesc("id");

        return queryWrapper;
    }

    @Override
    public Page<PolicyFollowVO> getPolicyFollowVOPage(Page<PolicyFollow> policyFollowPage) {
        List<PolicyFollow> policyFollowList = policyFollowPage.getRecords();
        Page<PolicyFollowVO> policyFollowVOPage = new Page<>(policyFollowPage.getCurrent(), policyFollowPage.getSize(), policyFollowPage.getTotal());
        if (CollUtil.isEmpty(policyFollowList)) {
            return policyFollowVOPage;
        }
        // 对象列表 => 封装对象列表
        List<PolicyFollowVO> policyFollowVOList = policyFollowList.stream().map(PolicyFollowVO::objToVo).collect(Collectors.toList());

        return policyFollowVOPage.setRecords(policyFollowVOList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePolicyFollow(PolicyFollowUpdateRequest policyFollowUpdateRequest) {
        // 校验参数
        if (StringUtils.isBlank(policyFollowUpdateRequest.getPolicyBizId())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        String policyBizId = policyFollowUpdateRequest.getPolicyBizId();
        PolicyFollow policyFollow = getByPolicyBizId(policyBizId);
        if (policyFollow == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR.getCode(), ErrorCode.NOT_FOUND_ERROR.getMessage());
        }
        // 跟进信息
        PolicyFollowUpdateDto policyFollowUpdateDto = policyFollowUpdateRequest.getPolicyFollowUpdateDto();
        if (policyFollowUpdateDto != null) {
            BeanUtils.copyProperties(policyFollowUpdateDto, policyFollow, "id", "policyBizId");

            // 计算冷却期结束日期
            if (policyFollowUpdateDto.getCoolingOffDays() != null && policyFollowUpdateDto.getEffectiveDate() != null) {
                policyFollow.setCoolingOffEndDate(DateUtil.offset(policyFollowUpdateDto.getEffectiveDate(), DateField.DAY_OF_MONTH, policyFollowUpdateDto.getCoolingOffDays()));
            }
            // 获取币种字典值
            policyFollow.setPolicyCurrency(this.getCurrencyValue(policyFollowUpdateDto.getPolicyCurrency()));
        }
        // 设置核保信息
        setValidPolicyInfo(policyFollow, policyFollowUpdateRequest.getVerifyPolicyInfo());
        // 设置保单邮寄
        setPolicyMailing(policyFollow, policyFollowUpdateRequest.getPolicyMailing());

        // 获取当前登录用户
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();
        policyFollow.setUpdaterId(loginUserId);
        policyFollow.setUpdateTime(new Date());

        return updateById(policyFollow);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePolicyFollowDto(PolicyFollowDto policyFollowDto) {
        // 校验参数
        if (StringUtils.isBlank(policyFollowDto.getPolicyBizId())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        String policyBizId = policyFollowDto.getPolicyBizId();
        PolicyFollow policyFollow = getByPolicyBizId(policyBizId);
        if (policyFollow == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR.getCode(), "新单跟进记录不存在");
        }

        // 复制属性，排除系统字段
        BeanUtils.copyProperties(policyFollowDto, policyFollow, "id", "policyBizId", "brokerList", "signerList");

        // 计算冷却期结束日期
        if (policyFollowDto.getCoolingOffDays() != null && policyFollowDto.getEffectiveDate() != null) {
            policyFollow.setCoolingOffEndDate(DateUtil.offset(policyFollowDto.getEffectiveDate(), DateField.DAY_OF_MONTH, policyFollowDto.getCoolingOffDays()));
        }

        // 获取当前登录用户
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();
        policyFollow.setUpdaterId(loginUserId);
        policyFollow.setUpdateTime(new Date());

        boolean result = updateById(policyFollow);


        return result;
    }

    private void setPolicyMailing(PolicyFollow policyFollow, PolicyMailing policyMailing) {
        if (policyMailing == null) {
            return;
        }
        policyFollow.setMailingMethod(policyMailing.getMailingMethod());
//        policyFollow.setBrokerSignDate(policyMailing.getBrokerSignDate());
//        policyFollow.setInsurerMailingDate(policyMailing.getInsurerMailingDate());
//        policyFollow.setCustomerSignDate(policyMailing.getCustomerSignDate());
    }

    private void setValidPolicyInfo(PolicyFollow policyFollow, VerifyPolicyInfo verifyPolicyInfo) {
        if (verifyPolicyInfo == null) {
            return;
        }
        policyFollow.setSubmitDate(verifyPolicyInfo.getSubmitDate());
        policyFollow.setSignDate(verifyPolicyInfo.getSignDate());
        policyFollow.setIssueDate(verifyPolicyInfo.getIssueDate());
        policyFollow.setEffectiveDate(verifyPolicyInfo.getEffectiveDate());
//        policyFollow.setIsPrepaid(verifyPolicyInfo.getIsPrepaid());
        policyFollow.setPrepaidAmount(verifyPolicyInfo.getPrepaidAmount());
        policyFollow.setPrepaidAmountAfterDiscount(verifyPolicyInfo.getPrepaidAmountAfterDiscount());
        policyFollow.setPolicyExpirationDate(verifyPolicyInfo.getPolicyExpirationDate());
    }

    @Override
    public PolicyFollowVO getPolicyFollowVO(PolicyFollow policyFollow) {
        if (policyFollow == null) {
            return null;
        }
        PolicyFollowVO policyFollowVO = PolicyFollowVO.objToVo(policyFollow);
        // 关联查询转介人
        QueryWrapper<PolicyBroker> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("policy_biz_id", policyFollow.getPolicyBizId());

        return policyFollowVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> addPolicyFollow(PolicyFollowAddRequest policyFollowAddRequest) {
        PolicyFollow policyFollow = new PolicyFollow();
        BeanUtils.copyProperties(policyFollowAddRequest, policyFollow);
        // 生成新单编号
        String policyBizId = RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_POLICY.getCode());
        policyFollow.setPolicyBizId(policyBizId);

        // 计算冷却期结束日期
        if (policyFollowAddRequest.getCoolingOffDays() != null) {
            policyFollow.setCoolingOffEndDate(DateUtil.offset(policyFollowAddRequest.getEffectiveDate(), DateField.DAY_OF_MONTH, policyFollowAddRequest.getCoolingOffDays()));
        }
        // 获取币种字典值
        policyFollow.setPolicyCurrency(this.getCurrencyValue(policyFollowAddRequest.getCurrency()));


        // 保存转介人
        List<PolicyBroker> policyBrokerList = policyFollowAddRequest.getBrokerList();
        if (CollUtil.isNotEmpty(policyBrokerList)) {
            policyBrokerList.forEach(policyBroker -> {
                policyBroker.setPolicyBizId(policyBizId);
            });
        }

        this.save(policyFollow);
        policyBrokerService.saveBatch(policyBrokerList);

        // 保险产品相关字段不为空，则查询获取保单预计来佣
//        String policyNo = policyFollowAddRequest.getPolicyNo();
//        String productLaunchBizId = policyFollowAddRequest.getProductLaunchBizId();
//        String insuranceCompanyBizId = policyFollowAddRequest.getInsuranceCompanyBizId();
//        String reconciliationCompany = policyFollowAddRequest.getReconciliationCompany();
//        String reconciliationCompanyCode = policyFollowAddRequest.getReconciliationCompanyCode();
//        String reconciliationCompanyBizId = policyFollowAddRequest.getReconciliationCompanyBizId();
//        // 保存保单预计来佣
//        commissionExpectedService.getExpectedCommissionByProductlaunchId(policyNo, productLaunchBizId, insuranceCompanyBizId, reconciliationCompany, reconciliationCompanyCode, reconciliationCompanyBizId);

        // 返回新单跟进唯一业务ID
        return Collections.singletonMap("policyBizId", policyBizId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> addPolicyFollowDto(PolicyFollowDto policyFollowDto) {
        PolicyFollow policyFollow = new PolicyFollow();
        // 复制属性，排除系统字段
        BeanUtils.copyProperties(policyFollowDto, policyFollow, "id", "policyBizId", "brokerList", "signerList");

        // 生成新单编号
        String policyBizId = RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_POLICY.getCode());
        policyFollow.setPolicyBizId(policyBizId);

        // 计算冷却期结束日期
        if (policyFollowDto.getCoolingOffDays() != null && policyFollowDto.getEffectiveDate() != null) {
            policyFollow.setCoolingOffEndDate(DateUtil.offset(policyFollowDto.getEffectiveDate(), DateField.DAY_OF_MONTH, policyFollowDto.getCoolingOffDays()));
        }

        // 获取当前登录用户
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();
        policyFollow.setCreatorId(loginUserId);
        policyFollow.setCreateTime(new Date());
        policyFollow.setUpdaterId(loginUserId);
        policyFollow.setUpdateTime(new Date());


        this.save(policyFollow);


        // 返回新单跟进唯一业务ID
        return Collections.singletonMap("policyBizId", policyBizId);
    }


    @Override
     public Boolean addToPolicy(List<String> policyNoList) {
         if (CollectionUtils.isEmpty(policyNoList)) {
             throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "保单号列表不能为空");
         }
         // 获取当前登录用户
         AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
         String loginUserId = currentLoginUser.getId().toString();

         // 查询所有跟进记录
         List<PolicyFollow> policyFollowList = list(new QueryWrapper<PolicyFollow>().in("policy_no", policyNoList));
         for (PolicyFollow policyFollow : policyFollowList) {
             // 查询保单是否存在
             String policyBizId = policyFollow.getPolicyBizId();
             Policy policy = policyService.getOne(new QueryWrapper<Policy>().eq("policy_biz_id", policyBizId));
             if (policy != null) {
                 // 更新
                 BeanUtils.copyProperties(policyFollow, policy, "id");
                 policy.setUpdaterId(loginUserId);
                 policy.setUpdateTime(new Date());

                 policyService.updateById(policy);
             } else {
                 // 不存在则创建
                 policy = new Policy();
                 BeanUtils.copyProperties(policyFollow, policy, "id");
                 policy.setId(null);
                 policy.setPolicyBizId(policyBizId);
                 policy.setCreatorId(loginUserId);
                 policy.setCreateTime(new Date());
                 policy.setUpdaterId(loginUserId);
                 policy.setUpdateTime(new Date());

                 policyService.save(policy);
             }
         }
         return true;
     }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean changePolicyFollowStatus(ChangePolicyFollowStatusRequest changePolicyFollowStatusRequest, PolicyFollow policyFollow) {
        if (changePolicyFollowStatusRequest == null || StringUtils.isBlank(changePolicyFollowStatusRequest.getPolicyBizId())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        if (policyFollow == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR.getCode(), ErrorCode.NOT_FOUND_ERROR.getMessage());
        }
        // 校验状态是否存在
        PolicyFollowStatusEnum policyFollowStatusEnum = PolicyFollowStatusEnum.getEnumByValue(changePolicyFollowStatusRequest.getStatus());
        if (policyFollowStatusEnum == null) {
            throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "跟进状态不存在");
        }
        // 获取当前跟进状态
        PolicyFollowStatusEnum currentStatusEnum = PolicyFollowStatusEnum.getEnumByValue(policyFollow.getStatus());
        // 校验状态是否可变更 - 终态状态不能变更
        if (PolicyFollowStatusEnum.EFFECTIVE.equals(currentStatusEnum)
                || PolicyFollowStatusEnum.DECLINED.equals(currentStatusEnum)
                || PolicyFollowStatusEnum.CANCELLED.equals(currentStatusEnum)
                || PolicyFollowStatusEnum.CLOSED.equals(currentStatusEnum)
                || PolicyFollowStatusEnum.LAPSED.equals(currentStatusEnum)
        ) {
            throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "生效、拒保、取消投保、关闭、失效状态不能变更");
        }

        String policyBizId = changePolicyFollowStatusRequest.getPolicyBizId();

        // 保单号和转接人都有的情况下，才能修改为生效状态
        if (PolicyFollowStatusEnum.EFFECTIVE.equals(policyFollowStatusEnum)) {
            if (StringUtils.isBlank(policyFollow.getPolicyNo())) {
                throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "保单号不能为空，才能修改为生效状态");
            }
            boolean exists = policyBrokerService.exists(new QueryWrapper<PolicyBroker>().eq("policy_biz_id", policyBizId));
            if (!exists) {
                throw new BusinessException(ResultCode.PARAM_CHECK_ERROR.getCode(), "转接人不能为空，才能修改为生效状态");
            }
        }

        // 获取当前登录用户
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();

        policyFollow.setStatus(changePolicyFollowStatusRequest.getStatus());
        policyFollow.setNextStatusList(getNextStatus(policyFollowStatusEnum));
        policyFollow.setUpdaterId(loginUserId);
        policyFollowService.updateById(policyFollow);

        // 如果是生效状态，同步到保单库
        if (PolicyFollowStatusEnum.EFFECTIVE.equals(policyFollowStatusEnum)) {
            addToPolicy(Collections.singletonList(policyFollow.getPolicyNo()));
        }

        // 新增新单状态记录
        PolicyFollowRecord policyFollowRecord = new PolicyFollowRecord();
        policyFollowRecord.setId(null);
        policyFollowRecord.setPolicyBizId(policyBizId);
        policyFollowRecord.setTitle(Objects.requireNonNull(policyFollowStatusEnum.getItemLabel()));
        policyFollowRecord.setMessage(changePolicyFollowStatusRequest.getMessage());
        policyFollowRecord.setCreatorId(loginUserId);
        policyFollowRecord.setCreateTime(new Date());
        policyFollowRecordService.save(policyFollowRecord);

        return true;
    }

    @Override
    public String getNextStatus(PolicyFollowStatusEnum policyFollowStatusEnum) {
        // 根据当前状态返回可能的下一步状态
        switch (policyFollowStatusEnum) {
            case PENDING_SIGN:
                return PolicyFollowStatusEnum.SIGNED.getItemValue() + ","
                        + PolicyFollowStatusEnum.CANCELLED.getItemValue();
            case SIGNED:
                return PolicyFollowStatusEnum.WAITING_PAYMENT.getItemValue() + ","
                        + PolicyFollowStatusEnum.CANCELLED.getItemValue();
            case WAITING_PAYMENT:
                return PolicyFollowStatusEnum.PREMIUM_RECONCILING.getItemValue() + ","
                        + PolicyFollowStatusEnum.CANCELLED.getItemValue();
            case PREMIUM_RECONCILING:
                return PolicyFollowStatusEnum.PREMIUM_RECONCILED_UNDERWRITING.getItemValue();
            case PREMIUM_RECONCILED_UNDERWRITING:
                return PolicyFollowStatusEnum.EFFECTIVE.getItemValue() + ","
                        + PolicyFollowStatusEnum.DECLINED.getItemValue() + ","
                        + PolicyFollowStatusEnum.DELAYED_UNDERWRITING.getItemValue();
            case DELAYED_UNDERWRITING:
                return PolicyFollowStatusEnum.PREMIUM_RECONCILED_UNDERWRITING.getItemValue() + ","
                        + PolicyFollowStatusEnum.DECLINED.getItemValue() + ","
                        + PolicyFollowStatusEnum.CANCELLED.getItemValue();
            default:
                return "";
        }
    }

    @Override
    public String getCurrencyValue(String currency) {
        if (StringUtils.isBlank(currency)) {
            return null;
        }
        switch (currency) {
            case "美元":
                currency = "USD";
                break;
            case "人民幣":
                currency = "CNY";
                break;
            case "港幣":
                currency = "HKD";
                break;
            case "澳元":
                currency = "AUD";
                break;
            case "加元":
                currency = "CAD";
                break;
            case "欧元":
                currency = "EUR";
                break;
            case "英鎊":
                currency = "GBP";
                break;
            case "新加坡元":
                currency = "SGD";
                break;
            default:
                break;
        }
        return currency;
    }

    @Override
    public PolicyReportData queryPolicyReportData(String policyBizId) {
        // 查询主险信息
        PolicyReportData policyReportData = this.baseMapper.queryPolicyReportData(policyBizId);
        // 处理附加险信息
        List<PolicyAdditional> additionalList= policyAdditionalService.list(new QueryWrapper<PolicyAdditional>().eq("policy_biz_id", policyBizId));
        List<PolicyReportData.AdditionalInsurance> additionalInsurances = new ArrayList<>();
        if (CollUtil.isNotEmpty(additionalList)) {
            for (PolicyAdditional additional : additionalList) {
                PolicyReportData.AdditionalInsurance additionalInsurance = new PolicyReportData.AdditionalInsurance();
                additionalInsurance.setName(additional.getAddProductName());
                additionalInsurance.setPaymentTerm(null);
                additionalInsurance.setCurrency(getCurrencyValue(additional.getCurrency()));
                additionalInsurance.setFirstYearAmount(additional.getPremium());
                additionalInsurances.add(additionalInsurance);
            }
        }
        // 处理附加险信息
        policyReportData.setAdditionalInsurances(additionalInsurances);
        // 处理服务经理
        String signerList = policyReportData.getServiceManager();
        if (StringUtils.isNotBlank(signerList)) {
            PolicySigner[] signers = GSONUtil.fromJson(signerList, PolicySigner[].class);
            policyReportData.setServiceManager(signers[0].getSigner());
        }
        // 处理位置
        policyReportData.setLocation("香港");
        return policyReportData;
    }

    /**
     * 根据保单号查询保单跟进信息
     * @param policyNo
     * @return
     */
    @Override
    public PolicyFollow queryOneByPolicyNo(String policyNo) {
        return this.getOne(new LambdaQueryWrapper<PolicyFollow>()
                .eq(PolicyFollow::getPolicyNo,policyNo)
                .last(" limit 1 ")
        );
    }

    @Override
    public Boolean uploadAttachment(AttachmentUploadRequest attachmentUploadRequest) {
        String policyBizId = attachmentUploadRequest.getPolicyBizId();
        if (policyBizId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        String fileName = attachmentUploadRequest.getFileName();
        if (fileName == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "fileName不能为空");
        }
        String fileUrl = attachmentUploadRequest.getFileUrl();
        if (fileUrl == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "fileUrl不能为空");
        }
        String ossFileBizId = attachmentUploadRequest.getOssFileBizId();
        if (ossFileBizId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR.getCode(), "ossFileBizId不能为空");
        }

        PolicyFollowFile policyFollowFile = new PolicyFollowFile();
        policyFollowFile.setPolicyBizId(attachmentUploadRequest.getPolicyBizId());
        policyFollowFile.setOssFileBizId(attachmentUploadRequest.getOssFileBizId());
        policyFollowFile.setFileName(attachmentUploadRequest.getFileName());
        policyFollowFile.setFileUrl(attachmentUploadRequest.getFileUrl());

        return policyFollowFileService.save(policyFollowFile);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveInitialPayment(InitialPaymentSaveRequest initialPaymentSaveRequest) {
        // 校验参数
        if (StringUtils.isBlank(initialPaymentSaveRequest.getPolicyBizId())) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }

        String policyBizId = initialPaymentSaveRequest.getPolicyBizId();
        PolicyFollow policyFollow = getByPolicyBizId(policyBizId);
        if (policyFollow == null) {
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "新单跟进记录不存在");
        }

        // 获取当前登录用户
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();

        // 更新相关字段
        boolean result = this.lambdaUpdate()
                .eq(PolicyFollow::getPolicyBizId, policyBizId)
                .set(initialPaymentSaveRequest.getInitialPremium() != null, PolicyFollow::getInitialPremium, initialPaymentSaveRequest.getInitialPremium())
                .set(initialPaymentSaveRequest.getPolicyLevy() != null, PolicyFollow::getPolicyLevy, initialPaymentSaveRequest.getPolicyLevy())
                .set(initialPaymentSaveRequest.getInitialPaymentMethod() != null, PolicyFollow::getInitialPaymentMethod, initialPaymentSaveRequest.getInitialPaymentMethod())
                .set(initialPaymentSaveRequest.getInitialPremiumPaid() != null, PolicyFollow::getInitialPremiumPaid, initialPaymentSaveRequest.getInitialPremiumPaid())
                .set(initialPaymentSaveRequest.getInitialPremiumDue() != null, PolicyFollow::getInitialPremiumDue, initialPaymentSaveRequest.getInitialPremiumDue())
                .set(initialPaymentSaveRequest.getInitialPremiumTotal() != null, PolicyFollow::getInitialPremiumTotal, initialPaymentSaveRequest.getInitialPremiumTotal())
                .set(initialPaymentSaveRequest.getLatestPaymentDate() != null, PolicyFollow::getLatestPaymentDate, initialPaymentSaveRequest.getLatestPaymentDate())
                .set(initialPaymentSaveRequest.getInitialPremiumDiscount() != null, PolicyFollow::getInitialPremiumDiscount, initialPaymentSaveRequest.getInitialPremiumDiscount())
                .set(initialPaymentSaveRequest.getInitialPaymentStatus() != null, PolicyFollow::getInitialPaymentStatus, initialPaymentSaveRequest.getInitialPaymentStatus())
                .set(PolicyFollow::getUpdaterId, loginUserId)
                .set(PolicyFollow::getUpdateTime, new Date())
                .update();

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveMailingInfo(MailingInfoSaveRequest mailingInfoSaveRequest) {
        // 校验参数
        if (StringUtils.isBlank(mailingInfoSaveRequest.getPolicyBizId())) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }

        String policyBizId = mailingInfoSaveRequest.getPolicyBizId();
        PolicyFollow policyFollow = getByPolicyBizId(policyBizId);
        if (policyFollow == null) {
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "新单跟进记录不存在");
        }

        // 获取当前登录用户
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();

        // 更新邮寄信息相关字段
        boolean result = this.lambdaUpdate()
                .eq(PolicyFollow::getPolicyBizId, policyBizId)
                .set(mailingInfoSaveRequest.getMailingMethod() != null, PolicyFollow::getMailingMethod, mailingInfoSaveRequest.getMailingMethod())
                .set(mailingInfoSaveRequest.getDeliveryNo() != null, PolicyFollow::getDeliveryNo, mailingInfoSaveRequest.getDeliveryNo())
                .set(mailingInfoSaveRequest.getBrokerSignDate() != null, PolicyFollow::getBrokerSignDate, mailingInfoSaveRequest.getBrokerSignDate())
                .set(mailingInfoSaveRequest.getCustomerSignDate() != null, PolicyFollow::getCustomerSignDate, mailingInfoSaveRequest.getCustomerSignDate())
                .set(PolicyFollow::getUpdaterId, loginUserId)
                .set(PolicyFollow::getUpdateTime, new Date())
                .update();

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchSaveBrokers(BrokerBatchSaveRequest brokerBatchSaveRequest) {
        // 校验参数
        if (StringUtils.isBlank(brokerBatchSaveRequest.getPolicyBizId())) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }

        String policyBizId = brokerBatchSaveRequest.getPolicyBizId();
        PolicyFollow policyFollow = getByPolicyBizId(policyBizId);
        if (policyFollow == null) {
            throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "新单跟进记录不存在");
        }

        if (org.apache.commons.collections4.CollectionUtils.isEmpty(brokerBatchSaveRequest.getBrokerList())) {
            throw new BusinessException(ResultCode.PARAMS_ERROR.getCode(), "介绍人列表不能为空");
        }

        // 获取当前登录用户
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();

        // 删除该 policyBizId 下的所有现有介绍人
        policyBrokerService.lambdaUpdate()
                .eq(PolicyBroker::getPolicyBizId, policyBizId)
                .remove();

        // 批量插入新的介绍人记录
        List<PolicyBroker> brokerList = new ArrayList<>();
        for (BrokerBatchSaveRequest.BrokerInfo brokerInfo : brokerBatchSaveRequest.getBrokerList()) {
            PolicyBroker policyBroker = new PolicyBroker();
            policyBroker.setPolicyBizId(policyBizId);
            policyBroker.setPolicyNo(policyFollow.getPolicyNo());
            policyBroker.setBrokerName(brokerInfo.getBrokerName());
            policyBroker.setBrokerBizId(brokerInfo.getBrokerBizId());
            policyBroker.setGender(brokerInfo.getGender());
            policyBroker.setInternalCode(brokerInfo.getInternalCode());
            policyBroker.setTeam(brokerInfo.getTeam());
            policyBroker.setTeamBizId(brokerInfo.getTeamBizId());
            policyBroker.setBrokerRatio(brokerInfo.getBrokerRatio());
            policyBroker.setRemark(brokerInfo.getRemark());
            policyBroker.setIsDeleted(0);
            policyBroker.setCreatorId(loginUserId);
            policyBroker.setCreateTime(new Date());
            policyBroker.setUpdaterId(loginUserId);
            policyBroker.setUpdateTime(new Date());
            brokerList.add(policyBroker);
        }

        return policyBrokerService.saveBatch(brokerList);
    }

}

