package com.yd.csf.api.controller;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.auth.core.dto.AuthUserDto;
import com.yd.auth.core.utils.SecurityUtil;
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.dto.CommissionExcelDTO;
import com.yd.csf.api.dto.PolicyExcelDTO;
import com.yd.csf.api.dto.PolicyFollowDTO;
import com.yd.csf.api.listener.PolicyDataListener;
import com.yd.csf.service.common.ErrorCode;
import com.yd.csf.service.component.PolicyReportPdfService;
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.vo.PolicyFollowDetailVO;
import com.yd.csf.service.vo.PolicyFollowRecordVO;
import com.yd.csf.service.vo.PolicyFollowVO;
import com.yd.product.feign.client.expectedcommissionratio.ApiExpectedCommissionRatioFeignClient;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 新单跟进接口
 *
 * @author jianan
 * @since 2025-07-31
 */
@RestController
@RequestMapping("/policy_follow")
@Tag(name = "新单跟进接口")
public class ApiPolicyFollowController {

    private static final Logger log = LoggerFactory.getLogger(ApiPolicyFollowController.class);

    private final DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");

    @Resource
    private PolicyFollowService policyFollowService;
    @Resource
    private PolicyService policyService;
    @Resource
    private PolicyBrokerService policyBrokerService;
    @Resource
    private PolicyDataListener policyDataListener;
    @Resource
    private CommissionExpectedService commissionExpectedService;
    @Resource
    private CustomerService customerService;
    @Resource
    private ReconciliationCompanyService reconciliationCompanyService;
    @Resource
    private PolicyFollowRecordService policyFollowRecordService;
    @Resource
    private PolicyFollowFileService policyFollowFileService;
    @Resource
    private PolicyReportPdfService policyReportPdfService;
    @Resource
    private ApiExpectedCommissionRatioFeignClient apiExpectedCommissionRatioFeignClient;


    @PostMapping("/upload/excel")
    @Transactional(rollbackFor = Exception.class)
    public Result<Boolean> uploadExcel(@RequestParam("file") MultipartFile file) throws Exception {
        // 创建监听器用于读取保单数据
        PolicyDataListener policyDataListener = new PolicyDataListener();

        // 一次性读取所有Sheet
        ExcelReader excelReader = EasyExcel.read(file.getInputStream()).build();

        // 1. 读取保单数据
        ReadSheet readSheet1 = EasyExcel.readSheet("保单")
                .head(PolicyExcelDTO.class)
                .registerReadListener(policyDataListener)
                .build();
        excelReader.read(readSheet1);

        // 2. 读取预计来佣数据
        List<CommissionExcelDTO> dataList = new ArrayList<>();
        ReadSheet readSheet2 = EasyExcel.readSheet("预计来佣")
                .head(CommissionExcelDTO.class)
                .registerReadListener(new AnalysisEventListener<CommissionExcelDTO>() {
                    @Override
                    public void invoke(CommissionExcelDTO data, AnalysisContext context) {
                        dataList.add(data);
                    }

                    @Override
                    public void doAfterAllAnalysed(AnalysisContext context) {
                        // 读取完成
                    }
                })
                .build();
        excelReader.read(readSheet2);

        // 关闭读取器
        excelReader.finish();

        List<PolicyExcelDTO> dtoList = policyDataListener.getList();

        // 校验保单号是否存在
        String validateMsg = validate(dtoList);
        if (StringUtils.isNotBlank(validateMsg)) return Result.fail(ErrorCode.OPERATION_ERROR.getCode(), validateMsg);

        // 保存对账公司
        Set<String> reconciliationCompanyNames = dtoList.stream()
                .map(PolicyExcelDTO::getReconciliationCompany)
                .collect(Collectors.toSet());
        List<ReconciliationCompany> reconciliationCompanyList = saveReconciliationCompany(reconciliationCompanyNames);
        // 关联对账公司
        Map<String, String> reconciliationCompanyMap = reconciliationCompanyList.stream()
                .collect(Collectors.toMap(ReconciliationCompany::getCompanyName, ReconciliationCompany::getReconciliationCompanyBizId));

        // 转换为PolicyFollow对象
        List<PolicyFollowDTO> list = convertToObj(dtoList, reconciliationCompanyMap);

        List<PolicyFollow> policyFollowList = new ArrayList<>();
        List<Policy> policyList = new ArrayList<>();
        List<PolicyBroker> policyBrokerList = new ArrayList<>();
        for (PolicyFollowDTO policyFollow : list) {
            policyFollowList.add(policyFollow.getPolicyFollow());
            policyBrokerList.addAll(policyFollow.getBrokerList());
//            policyList.add(policyFollow.getPolicy());
            reconciliationCompanyNames.add(policyFollow.getPolicy().getReconciliationCompany());
        }

        policyFollowService.saveBatch(policyFollowList);
//        policyService.saveBatch(policyList);
        policyBrokerService.saveBatch(policyBrokerList);

        // 获取当前登录用户的ID
        AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
        String loginUserId = currentLoginUser.getId().toString();
        // todo 保存预计来佣, 查询产品获取预计来佣比例
//        List<CommissionExpected> commissionExpectedList = new ArrayList<>();
//        for (CommissionExcelDTO commissionExcelDTO : dataList) {
//            CommissionExpected commissionExpected = CommissionExcelDTO.convertToCommissionExpectedObj(commissionExcelDTO, loginUserId);
//            commissionExpected.setReconciliationCompanyBizId(reconciliationCompanyMap.get(commissionExcelDTO.getReconciliationCompany()));
//            commissionExpectedList.add(commissionExpected);
//        }
//        commissionExpectedService.saveBatch(commissionExpectedList);

        return Result.success(true);
    }

    private List<ReconciliationCompany> saveReconciliationCompany(Set<String> reconciliationCompanyNames) {
        List<ReconciliationCompany> reconciliationCompanyList = new ArrayList<>();

        // 查询已存在的对账公司
        List<ReconciliationCompany> existingCompanies = reconciliationCompanyService.lambdaQuery()
                .in(ReconciliationCompany::getCompanyName, reconciliationCompanyNames)
                .list();
        Set<String> existingCompanyNames = existingCompanies.stream()
                .map(ReconciliationCompany::getCompanyName)
                .collect(Collectors.toSet());

        // 过滤掉已存在的公司名称
        Set<String> newCompanyNames = reconciliationCompanyNames.stream()
                .filter(name -> !existingCompanyNames.contains(name))
                .collect(Collectors.toSet());

        // 只保存新的对账公司
        for (String reconciliationCompanyName : newCompanyNames) {
            ReconciliationCompany reconciliationCompany = new ReconciliationCompany();
            reconciliationCompany.setReconciliationCompanyBizId(RandomStringGenerator.generateBizId16("reconciliation_company"));
            reconciliationCompany.setCompanyName(reconciliationCompanyName);
            reconciliationCompanyList.add(reconciliationCompany);
        }

        if (!reconciliationCompanyList.isEmpty()) {
            reconciliationCompanyService.saveBatch(reconciliationCompanyList);
        }

        // 返回所有对账公司（包括已存在的和新建的）
        List<ReconciliationCompany> allCompanies = new ArrayList<>(existingCompanies);
        allCompanies.addAll(reconciliationCompanyList);
        return allCompanies;
    }

    private String validate(List<PolicyExcelDTO> dtoList) {
        String validateMsg = "";
        // 校验保单号是否为空
        if (dtoList.isEmpty()) {
            validateMsg = "保单数据不能为空";
        }

        Set<String> policyNos = dtoList.stream()
                .map(PolicyExcelDTO::getPolicyNo)
                .collect(Collectors.toSet());
        List<Policy> existingPolicies = policyService.lambdaQuery()
                .in(Policy::getPolicyNo, policyNos)
                .list();
        Set<String> existingPolicyNos = existingPolicies.stream()
                .map(Policy::getPolicyNo)
                .collect(Collectors.toSet());
        if (CollectionUtils.isNotEmpty(existingPolicyNos)) {
            validateMsg = "保单号 " + String.join(", ", existingPolicyNos) + " 已存在，请检查后重新上传!";
        }
        return validateMsg;
    }

    private List<PolicyFollowDTO> convertToObj(List<PolicyExcelDTO> list, Map<String, String> reconciliationCompanyMap) throws ParseException {
        List<PolicyFollowDTO> policyFollowDTOList = new ArrayList<>();

        // 获取所有保单持有人
        Set<String> customerNames = list.stream()
                .map(PolicyExcelDTO::getPolicyHolder)
                .collect(Collectors.toSet());
        // 根据保单持有人名称查询用户业务ID
        List<Customer> customerList = customerService.lambdaQuery()
                .in(Customer::getNamePyEn, customerNames)
                .list();
        // 构建保单持有人名称到用户业务ID的映射
        Map<String, String> customerNameToBizIdMap = customerList.stream()
                .collect(Collectors.toMap(Customer::getNamePyEn, Customer::getCustomerBizId, (oldValue, newValue) -> oldValue));

        for (PolicyExcelDTO policyExcelDTO : list) {
            String policyNo = policyExcelDTO.getPolicyNo();
            // 生成新单编号
            String policyBizId = RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_POLICY.getCode());
            // 转换为PolicyFollow对象
            PolicyFollow policyFollow = new PolicyFollow();
            BeanUtils.copyProperties(policyExcelDTO, policyFollow);
            policyFollow.setPolicyBizId(policyBizId);
            policyFollow.setInitialPremium(decimalFormat.parse(policyExcelDTO.getInitialPremium()));
            policyFollow.setCustomerName(policyExcelDTO.getPolicyHolder());
            policyFollow.setCustomerBizId(customerNameToBizIdMap.get(policyExcelDTO.getPolicyHolder()));
            PolicyFollowStatusEnum policyFollowStatusEnum = PolicyFollowStatusEnum.getEnumByItemLabel(policyExcelDTO.getStatus());
            if (policyFollowStatusEnum == null) {
                policyFollow.setStatus(null);
            } else {
                policyFollow.setStatus(policyFollowStatusEnum.getItemValue());
            }
            policyFollow.setReconciliationCompanyBizId(reconciliationCompanyMap.get(policyExcelDTO.getReconciliationCompany()));
            if (policyFollow.getEffectiveDate()!= null && policyFollow.getCoolingOffDays() != null) {
                policyFollow.setCoolingOffEndDate(DateUtil.offset(policyFollow.getEffectiveDate(), DateField.DAY_OF_MONTH, policyFollow.getCoolingOffDays()));
            }
            // 获取币种字典值
            policyFollow.setCurrency(policyFollowService.getCurrencyValue(policyExcelDTO.getCurrency()));

            // 转换为Policy对象
            Policy policy = new Policy();
            BeanUtils.copyProperties(policyExcelDTO, policy);
            policy.setPolicyBizId(policyBizId);
            policy.setReconciliationCompanyBizId(policyFollow.getReconciliationCompanyBizId());
            policy.setCoolingOffEndDate(policyFollow.getCoolingOffEndDate());

            // 转换为PolicyBroker对象
            List<PolicyBroker> policyBrokerList = new ArrayList<>();
            if (StringUtils.isNotBlank(policyExcelDTO.getBrokerName1())) {
                policyBrokerList.add(getPolicyBroker(policyExcelDTO.getBrokerName1(), policyExcelDTO.getTeam1(), policyExcelDTO.getBrokerRatio1(), policyBizId, policyNo));
            }
            if (StringUtils.isNotBlank(policyExcelDTO.getBrokerName2())) {
                policyBrokerList.add(getPolicyBroker(policyExcelDTO.getBrokerName2(), policyExcelDTO.getTeam2(), policyExcelDTO.getBrokerRatio2(), policyBizId, policyNo));
            }
            if (StringUtils.isNotBlank(policyExcelDTO.getBrokerName3())) {
                policyBrokerList.add(getPolicyBroker(policyExcelDTO.getBrokerName3(), policyExcelDTO.getTeam3(), policyExcelDTO.getBrokerRatio3(), policyBizId, policyNo));
            }
            if (StringUtils.isNotBlank(policyExcelDTO.getBrokerName4())) {
                policyBrokerList.add(getPolicyBroker(policyExcelDTO.getBrokerName4(), policyExcelDTO.getTeam4(), policyExcelDTO.getBrokerRatio4(), policyBizId, policyNo));
            }
            if (StringUtils.isNotBlank(policyExcelDTO.getBrokerName5())) {
                policyBrokerList.add(getPolicyBroker(policyExcelDTO.getBrokerName5(), policyExcelDTO.getTeam5(), policyExcelDTO.getBrokerRatio5(), policyBizId, policyNo));
            }

            // 转换为PolicyFollowDTO对象
            PolicyFollowDTO policyFollowDTO = new PolicyFollowDTO();
            policyFollowDTO.setPolicyFollow(policyFollow);
            policyFollowDTO.setPolicy(policy);
            policyFollowDTO.setBrokerList(policyBrokerList);
            policyFollowDTOList.add(policyFollowDTO);
        }
        return policyFollowDTOList;
    }

    private PolicyBroker getPolicyBroker(String brokerName, String team, String brokerRatio, String policyBizId, String policyNo) {
        PolicyBroker policyBroker = new PolicyBroker();
        policyBroker.setPolicyBizId(policyBizId);
        policyBroker.setPolicyNo(policyNo);
        policyBroker.setBrokerName(brokerName);
        policyBroker.setTeam(team);
        policyBroker.setBrokerRatio(brokerRatio);
        return policyBroker;
    }

    /**
     * 创建新单跟进
     *
     * @param policyFollowAddRequest
     * @param request
     * @return
     */
    @Operation(summary = "创建新单跟进")
    @PostMapping("/add")
    public Result<Map<String, Object>> addPolicyFollow(@RequestBody PolicyFollowAddRequest policyFollowAddRequest, HttpServletRequest request) {
        if (policyFollowAddRequest == null) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMessage());
        }
        return Result.success(policyFollowService.addPolicyFollow(policyFollowAddRequest));
    }

    /**
     * 保存到保单库
     *
     * @param addToPolicyRequest
     * @param request
     * @return
     */
    @Operation(summary = "保存到保单库")
    @PostMapping("/addToPolicy")
    public Result<Boolean> addToPolicy(@RequestBody AddToPolicyRequest addToPolicyRequest, HttpServletRequest request) {
        if (CollectionUtils.isEmpty(addToPolicyRequest.getPolicyNoList())) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "保单号列表不能为空");
        }
        return Result.success(policyFollowService.addToPolicy(addToPolicyRequest.getPolicyNoList()));
    }

    /**
     * 删除新单跟进
     *
     * @param deleteRequest
     * @param request
     * @return
     */
    @Operation(summary = "删除新单跟进")
    @PostMapping("/delete")
    public Result<Boolean> deletePolicyFollow(@RequestBody PolicyFollowDeleteRequest deleteRequest, HttpServletRequest request) {
        if (StringUtils.isBlank(deleteRequest.getPolicyBizId())) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMessage());
        }
        String policyBizId = deleteRequest.getPolicyBizId();

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

        // 判断是否存在
        PolicyFollow oldFna = policyFollowService.getByPolicyBizId(policyBizId);
        if (oldFna == null) {
            return Result.fail(ErrorCode.NOT_FOUND_ERROR.getCode(), ErrorCode.NOT_FOUND_ERROR.getMessage());
        }
        // 仅本人或管理员可删除
//        if (!oldFna.getUserId().equals(loginUserId) && !userService.isAdmin(request)) {
//            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
//        }
        // 操作数据库
        boolean result = policyFollowService.removeById(oldFna.getId());
        if (!result) {
            return Result.fail(ErrorCode.OPERATION_ERROR.getCode(), ErrorCode.OPERATION_ERROR.getMessage());
        }
        return Result.success(result);
    }

    /**
     * 更新新单跟进
     *
     * @param policyFollowUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @Operation(summary = "更新新单跟进信息")
    public Result<Boolean> updatePolicyFollow(@RequestBody PolicyFollowUpdateRequest policyFollowUpdateRequest) {
        if (policyFollowUpdateRequest == null || StringUtils.isBlank(policyFollowUpdateRequest.getPolicyBizId())) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        return Result.success(policyFollowService.updatePolicyFollow(policyFollowUpdateRequest));
    }

    /**
     * 新单跟进上传附件
     *
     * @param attachmentUploadRequest
     * @return
     */
    @PostMapping("/attachment/upload")
    @Operation(summary = "新单跟进上传附件")
    public Result<Boolean> attachmentUpload(@RequestBody AttachmentUploadRequest attachmentUploadRequest) {
        if (StringUtils.isBlank(attachmentUploadRequest.getPolicyBizId())) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        return Result.success(policyFollowService.uploadAttachment(attachmentUploadRequest));
    }

    /**
     * 新单跟进附件列表分页查询
     *
     * @param queryRequest
     * @return
     */
    @PostMapping("/attachment/list/page")
    @Operation(summary = "新单跟进附件列表分页查询")
    public Result<Page<PolicyFollowFile>> attachmentListPage(@RequestBody PolicyFollowFileQueryRequest queryRequest) {
        if (StringUtils.isBlank(queryRequest.getPolicyBizId())) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        long current = queryRequest.getPageNo();
        long size = queryRequest.getPageSize();

        QueryWrapper<PolicyFollowFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("policy_biz_id", queryRequest.getPolicyBizId());
        queryWrapper.eq("is_deleted", 0);
        Page<PolicyFollowFile> policyFollowFilePage = policyFollowFileService.page(new Page<>(current, size), queryWrapper);
        return Result.success(policyFollowFilePage);
    }

    /**
     * 删除新单跟进附件
     *
     * @param fileId
     * @return
     */
    @DeleteMapping("/attachment/delete")
    @Operation(summary = "删除新单跟进附件")
    public Result<Boolean> deletePolicyFollowAttachment(@RequestParam("fileId") Long fileId) {
        if (fileId == null) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "fileId不能为空");
        }
        return Result.success(policyFollowFileService.removeById(fileId));
    }

    /**
     * 根据 policyBizId 获取新单跟进（封装类）
     *
     * @param policyBizId
     * @return
     */
    @GetMapping("/get/vo")
    @Operation(summary = "根据 policyBizId 获取新单跟进详情")
    public Result<PolicyFollowVO> getPolicyFollowByPolicyBizId(@RequestParam("policyBizId") String policyBizId, HttpServletRequest request) {
        if (StringUtils.isBlank(policyBizId)) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        // 查询数据库
        PolicyFollow policyFollow = policyFollowService.getByPolicyBizId(policyBizId);
        if (policyFollow == null) {
            return Result.fail(ErrorCode.NOT_FOUND_ERROR.getCode(), ErrorCode.NOT_FOUND_ERROR.getMessage());
        }
        // 异步查询产品上架信息表
        if (StringUtils.isNotBlank(policyFollow.getPolicyNo()) && StringUtils.isBlank(policyFollow.getProductLaunchBizId())) {
            // 异步查询产品上架信息表
//            ApiExpectedCommissionRatioPageRequest apiExpectedCommissionRatioPageRequest = new ApiExpectedCommissionRatioPageRequest();
//            apiExpectedCommissionRatioPageRequest.setPageNo(1);
//            apiExpectedCommissionRatioPageRequest.setPageSize(100);
//            apiExpectedCommissionRatioPageRequest.setWarrantyPeriod(String.valueOf(policyFollow.getPaymentTerm()));
//            Result<Page<ApiExpectedCommissionRatioPageResponse>> result = apiExpectedCommissionRatioFeignClient.page(apiExpectedCommissionRatioPageRequest);
//            if (result != null && result.getData() != null) {
//                List<ApiExpectedCommissionRatioPageResponse> records = (List<ApiExpectedCommissionRatioPageResponse>) result.getData();
//                if (CollectionUtils.isNotEmpty(records)) {
//                    policyFollow.setProductLaunchBizId(records.get(0).getProductLaunchBizId());
//                }
//            }
            PolicyFollow updatePolicyFollow = new PolicyFollow();
            updatePolicyFollow.setId(policyFollow.getId());
            updatePolicyFollow.setProductLaunchBizId("product_launch_kudwRqXsz1");
            policyFollowService.updateById(updatePolicyFollow);
        }



        // 获取封装类
        return Result.success(policyFollowService.getPolicyFollowVO(policyFollow));
    }

    @GetMapping("/detail/{policyBizId}")
    @Operation(summary = "根据 policyBizId 获取新单跟进聚合详情")
    public Result<PolicyFollowAggregateDto> getPolicyFollowAggregate(@PathVariable String policyBizId) {
        try {
            PolicyFollowAggregateDto result = policyFollowService.getPolicyFollowAggregate(policyBizId);
            return Result.success(result);
        } catch (Exception e) {
            log.error("获取新单跟进聚合详情失败, policyBizId: {}", policyBizId, e);
            return Result.fail("查询失败: " + e.getMessage());
        }
    }

    /**
     * 分页获取新单跟进列表（仅管理员可用）
     *
     * @param fnaQueryRequest
     * @return
     */
//    @PostMapping("/list/page")
//    public Result<Page<Customer>> listFnaByPage(@RequestBody FnaQueryRequest fnaQueryRequest) {
//        long current = fnaQueryRequest.getPageNo();
//        long size = fnaQueryRequest.getPageSize();
//        // 查询数据库
//        Page<Customer> fnaPage = policyFollowService.page(new Page<>(current, size),
//                policyFollowService.getQueryWrapper(fnaQueryRequest));
//        return Result.success(fnaPage);
//    }

    /**
     * 分页获取新单跟进列表
     *
     * @param policyFollowQueryRequest
     * @param request
     * @return
     */
    @PostMapping("/list/page/vo")
    @Operation(summary = "分页获取新单跟进列表")
    public Result<Page<PolicyFollowDetailVO>> listPolicyFollowByPage(@RequestBody PolicyFollowQueryRequest policyFollowQueryRequest,
                                                                     HttpServletRequest request) {
        long current = policyFollowQueryRequest.getPageNo();
        long size = policyFollowQueryRequest.getPageSize();

        // 查询数据库
        Page<PolicyFollow> policyFollowPage = policyFollowService.page(new Page<>(current, size),
                policyFollowService.getQueryWrapper(policyFollowQueryRequest));
        return Result.success(policyFollowService.getPolicyFollowDetailVOList(policyFollowPage));
    }

    /**
     * 修改跟进状态
     *
     * @param changePolicyFollowStatusRequest
     * @param request
     * @return
     */
    @PostMapping("/change_status")
    @Operation(summary = "修改跟进状态")
    public Result<Boolean> changePolicyFollowStatus(@RequestBody ChangePolicyFollowStatusRequest changePolicyFollowStatusRequest,
                                                    HttpServletRequest request) {
        if (changePolicyFollowStatusRequest == null || StringUtils.isBlank(changePolicyFollowStatusRequest.getPolicyBizId())) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        String policyBizId = changePolicyFollowStatusRequest.getPolicyBizId();
        PolicyFollow policyFollow = policyFollowService.getByPolicyBizId(policyBizId);
        if (policyFollow == null) {
            return Result.fail(ErrorCode.NOT_FOUND_ERROR.getCode(), ErrorCode.NOT_FOUND_ERROR.getMessage());
        }
        return Result.success(policyFollowService.changePolicyFollowStatus(changePolicyFollowStatusRequest, policyFollow));
    }

    /**
     * 新单跟进状态列表查询
     *
     * @param policyBizId
     * @return
     */
    @GetMapping("/status/list")
    @Operation(summary = "新单跟进状态列表查询")
    public Result<List<PolicyFollowRecordVO>> getPolicyFollowRecordList(@RequestParam("policyBizId") String policyBizId) {
        if (policyBizId == null) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "policyBizId不能为空");
        }
        QueryWrapper<PolicyFollowRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("policy_biz_id", policyBizId);
        queryWrapper.orderByDesc("id");
        List<PolicyFollowRecord> policyFollowStatusList = policyFollowRecordService.list(queryWrapper);
        return Result.success(policyFollowRecordService.getVOList(policyFollowStatusList));
    }

    /**
     * 生成签约单
     */
    @GetMapping(value = "/report/download", produces = "application/pdf")
    @Operation(summary = "生成签约单")
    public void previewPolicyReport(@RequestParam("policyBizId") String policyBizId,
                                    HttpServletResponse response) {

        PolicyReportData reportData = policyFollowService.queryPolicyReportData(policyBizId);
        if (reportData == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR.getCode(), ErrorCode.NOT_FOUND_ERROR.getMessage());
        }

//        reportData.setStartTime("2025-10-30");
//        reportData.setEndTime("2025-10-30");
//        reportData.setLocation("香港");
//        reportData.setServiceManager("Vickie");
//        reportData.setPolicyHolder("policyHolder");
//        reportData.setPolicyNumber("B635379588");
//        reportData.setInsuranceCompany("友邦保险");
//        reportData.setInsuredPerson("insuredPerson");
//        reportData.setInsurancePlan("环宇盈活储蓄保险计划");
//        reportData.setInsuredAge(1);
//        reportData.setCurrency("HKD");
//        reportData.setPaymentPeriod(5);
//        reportData.setAnnualAmount(BigDecimal.valueOf(30000.08));
//        reportData.setTotalPrepayment(BigDecimal.valueOf(150064.70));
//        reportData.setPremiumFee(BigDecimal.valueOf(12.86));

        try {
            log.info("收到PDF生成请求: {}", reportData);

            log.info("PolicyReportData 内容检查:");
            log.info("startTime: {}", reportData.getStartTime());
            log.info("endTime: {}", reportData.getEndTime());
            log.info("location: {}", reportData.getLocation());
            log.info("serviceManager: {}", reportData.getServiceManager());

            byte[] pdfBytes = policyReportPdfService.generatePolicyReport(reportData);

            if (pdfBytes == null || pdfBytes.length == 0) {
                log.error("生成的PDF为空");
                throw new BusinessException("生成的PDF内容为空");
            }

            log.info("PDF生成成功，大小: {} bytes", pdfBytes.length);

            // 设置下载响应头
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment; filename=policy-report-" +
                    reportData.getPolicyNumber() + ".pdf");
            response.setContentLength(pdfBytes.length);

            // 写入响应流
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(pdfBytes);
            outputStream.flush();

            log.info("PDF响应发送完成");

        } catch (Exception e) {
            log.error("PDF预览失败", e);
            throw new BusinessException("PDF预览失败: " + e.getMessage());
        }
    }

}