package com.yd.csf.api.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.common.enums.ResultCode;
import com.yd.common.result.Result;
import com.yd.csf.api.dto.QueryCommissionExpectedByPageResponse;
import com.yd.csf.api.dto.ReceivableReportResponse;
import com.yd.csf.service.common.ErrorCode;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.model.CommissionExpected;
import com.yd.csf.service.service.CommissionExpectedService;
import com.yd.csf.service.vo.CommissionExpectedExportDTO;
import com.yd.csf.service.vo.CommissionExpectedStatisticsVO;
import com.yd.csf.service.vo.CommissionExpectedVO;
import com.yd.csf.service.vo.ReceivableReportVO;
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.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;

/**
 * CommissionExpected接口
 *
 * @author jianan
 * @since 2025-08-31
 */
@RestController
@RequestMapping("/CommissionExpected")
@Tag(name = "预计入账接口")
public class ApiCommissionExpectedController {

    @Resource
    private CommissionExpectedService commissionExpectedService;

    /**
     * 批量新增预计入账
     *
     * @param commissionExpectedAddRequest
     * @param request
     * @return
     */
    @PostMapping("/add")
    @Operation(summary = "新增预计入账")
    public Result<Boolean> addCommissionExpected(@RequestBody CommissionExpectedAddRequest commissionExpectedAddRequest, HttpServletRequest request) {
        if (commissionExpectedAddRequest == null) {
            return Result.fail(ResultCode.PARAMS_ERROR.getCode(), ResultCode.PARAMS_ERROR.getMessage());
        }
        return Result.success(commissionExpectedService.addCommissionExpected(commissionExpectedAddRequest));
    }

    /**
     * 删除预计入账
     *
     * @param commissionExpectedBizId 预计入账业务id
     * @param request
     * @return
     */
    @DeleteMapping("/delete")
    @Operation(summary = "删除预计入账")
    public Result<Boolean> deleteCommissionExpected(@RequestParam("commissionExpectedBizId") String commissionExpectedBizId, HttpServletRequest request) {
        if (StringUtils.isBlank(commissionExpectedBizId)) {
            return Result.fail(ResultCode.PARAMS_ERROR.getCode(), "预计入账业务id不能为空");
        }
        return Result.success(commissionExpectedService.deleteCommissionExpected(commissionExpectedBizId));
    }

    /**
     * 更新预计入账
     *
     * @param commissionExpectedUpdateRequest
     * @return
     */
    @PostMapping("/update")
    @Operation(summary = "更新预计入账")
    public Result<Boolean> updateCommissionExpected(@RequestBody CommissionExpectedUpdateRequest commissionExpectedUpdateRequest) {
        if (commissionExpectedUpdateRequest == null || StringUtils.isBlank(commissionExpectedUpdateRequest.getCommissionExpectedBizId())) {
            return Result.fail(ResultCode.PARAMS_ERROR.getCode(), "commissionExpectedBizId不能为空");
        }
        return Result.success(commissionExpectedService.updateCommissionExpected(commissionExpectedUpdateRequest));
    }

    /**
     * 根据 CommissionExpectedBizId 获取CommissionExpected（封装类）
     *
     * @param commissionExpectedBizId 预计入账业务id
     * @return
     */
    @GetMapping("/get/vo")
    @Operation(summary = "预计入账详情")
    public Result<CommissionExpectedVO> getCommissionExpectedVOByBizId(String commissionExpectedBizId, HttpServletRequest request) {
        if (StringUtils.isBlank(commissionExpectedBizId)) {
            return Result.fail(ResultCode.PARAMS_ERROR.getCode(), "commissionExpectedBizId不能为空");
        }
        // 查询数据库
        CommissionExpected CommissionExpected = commissionExpectedService.getByBizId(commissionExpectedBizId);
        if (CommissionExpected == null) {
            return Result.fail(ResultCode.NULL_ERROR.getCode(), ResultCode.NULL_ERROR.getMessage());
        }

        // 获取封装类
        return Result.success(commissionExpectedService.getCommissionExpectedVO(CommissionExpected));
    }

    /**
     * 分页获取CommissionExpected列表（仅管理员可用）
     *
     * @param CommissionExpectedQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @Operation(summary = "分页获取预计入账列表", description = "可根据 reconciliation_company、commission_name、commission_period、amount 排序，默认按照佣金期数升序排序")
    public Result<Page<CommissionExpectedVO>> listCommissionExpectedByPage(@RequestBody CommissionExpectedQueryRequest CommissionExpectedQueryRequest) {
        // 校验参数
        if (CommissionExpectedQueryRequest == null || CommissionExpectedQueryRequest.getPolicyNo() == null) {
            return Result.fail(ResultCode.PARAMS_ERROR.getCode(), "保单号不能为空");
        }
        long current = CommissionExpectedQueryRequest.getPageNo();
        long size = CommissionExpectedQueryRequest.getPageSize();

        // 查询数据库
        Page<CommissionExpected> CommissionExpectedPage = commissionExpectedService.page(new Page<>(current, size),
                commissionExpectedService.getQueryWrapper(CommissionExpectedQueryRequest));
        return Result.success(commissionExpectedService.getCommissionExpectedVOPage(CommissionExpectedPage));
    }

    /**
     * 计算统计数据 总金额、总入账金额、待入账金额、已入账比例（已入账金额/总金额）、总保单数
     */
    @PostMapping("/statistics")
    @Operation(summary = "计算统计数据 总金额、总入账金额、待入账金额、已入账比例（已入账金额/总金额）、总保单数")
    public Result<CommissionExpectedStatisticsVO> getCommissionStatistics(@RequestBody CommissionExpectedStatisticsRequest commissionExpectedStatisticsRequest) {
        if (commissionExpectedStatisticsRequest == null) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMessage());
        }
        return Result.success(commissionExpectedService.getExpectedStatistics(commissionExpectedStatisticsRequest.getCommissionExpectedIds()));
    }

    /**
     * 应收款管理列表查询
     *
     * @param commissionExpectedQueryRequest
     * @return
     */
    @PostMapping("/queryCommissionExpectedByPage")
    @Operation(summary = "应收款管理列表查询")
    public Result<QueryCommissionExpectedByPageResponse> queryCommissionExpectedByPage(@RequestBody CommissionExpectedQueryRequest commissionExpectedQueryRequest) {
        long current = commissionExpectedQueryRequest.getPageNo();
        long size = commissionExpectedQueryRequest.getPageSize();

        // 查询列表数据
        QueryWrapper<CommissionExpected> queryWrapper = commissionExpectedService.getQueryWrapper(commissionExpectedQueryRequest);
        Page<CommissionExpected> commissionExpectedPage = commissionExpectedService.page(new Page<>(current, size),
                queryWrapper);

        // 查询统计数据
        List<CommissionExpected> commissionExpectedList = commissionExpectedService.list(queryWrapper);
        // 计算统计数据
        List<Long> expectedIds = commissionExpectedList.stream().map(CommissionExpected::getId).collect(Collectors.toList());
        CommissionExpectedStatisticsVO expectedStatisticsVO = commissionExpectedService.getExpectedStatistics(expectedIds);
        // 组装返回值
        QueryCommissionExpectedByPageResponse response = new QueryCommissionExpectedByPageResponse();
        response.setExpectedStatisticsVO(expectedStatisticsVO);
        response.setPage(commissionExpectedService.getCommissionExpectedVOPage(commissionExpectedPage));
        return Result.success(response);
    }

    /**
     * 应收款导出
     *
     * @param commissionExpectedQueryRequest
     * @return
     */
    @PostMapping("/export")
    @Operation(summary = "应收款导出")
    public void exportCommissionExpected(@RequestBody CommissionExpectedQueryRequest commissionExpectedQueryRequest, HttpServletResponse response) throws UnsupportedEncodingException {
        if (commissionExpectedQueryRequest == null) {
            throw new RuntimeException("查询参数不能为空");
        }

        // 设置响应头
        String fileName = URLEncoder.encode("应收款管理数据", "UTF-8").replaceAll("\\+", "%20");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 查询数据
        QueryWrapper<CommissionExpected> queryWrapper = commissionExpectedService.getQueryWrapper(commissionExpectedQueryRequest);
        List<CommissionExpected> commissionExpectedList = commissionExpectedService.list(queryWrapper);

        // 转换为导出DTO
        List<CommissionExpectedExportDTO> exportDataList = commissionExpectedList.stream()
                .map(CommissionExpectedExportDTO::convertToExportDTO)
                .collect(Collectors.toList());

        // 使用EasyExcel导出
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), CommissionExpectedExportDTO.class).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet("应收款数据").build();
            excelWriter.write(exportDataList, writeSheet);
        } catch (Exception e) {
            throw new RuntimeException("导出应收款数据失败", e);
        }

    }

    /**
     * 获取保单应收款
     */
    @PostMapping("/getExpectedCommissionByProductlaunchId")
    @Operation(summary = "获取保单应收款")
    public Result<Boolean> getExpectedCommissionByProductlaunchId(@RequestBody GetExpectedCommissionByProductlaunchIdRequest request) {
        if (request == null) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMessage());
        }
        commissionExpectedService.getExpectedCommissionByProductlaunchId(
                request.getPolicyNo(),
                request.getProductLaunchBizId(),
                request.getInsuranceCompanyBizId(),
                request.getReconciliationCompany(),
                request.getReconciliationCompanyCode(),
                request.getReconciliationCompanyBizId());

        return Result.success(true);
    }

    /**
     * 应收款报表
     *
     * @param commissionExpectedQueryRequest
     * @return
     */
    @PostMapping("/receivable_report")
    @Operation(summary = "应收款报表")
    public Result<ReceivableReportResponse> receivableReport(@RequestBody CommissionExpectedQueryRequest commissionExpectedQueryRequest) {
        // 构建查询条件
        QueryWrapper<CommissionExpected> queryWrapper = commissionExpectedService.getQueryWrapper(commissionExpectedQueryRequest);

        // 先查询所有符合条件的记录ID（用于统计）
        List<CommissionExpected> allCommissionExpectedList = commissionExpectedService.list(queryWrapper);
        List<Long> allExpectedIdList = allCommissionExpectedList.stream().map(CommissionExpected::getId).collect(Collectors.toList());

        // 查询统计数据（基于所有符合条件的记录）
        CommissionExpectedStatisticsVO statisticsVO = commissionExpectedService.getExpectedStatistics(allExpectedIdList);

        // 应收款报表分页查询 - 按保单号和期数维度统计
        Page<ReceivableReportVO> reportPage = new Page<>(commissionExpectedQueryRequest.getPageNo(), commissionExpectedQueryRequest.getPageSize());
        IPage<ReceivableReportVO> receivableReportPage = new Page<>(commissionExpectedQueryRequest.getPageNo(), commissionExpectedQueryRequest.getPageSize());
        if (!CollectionUtils.isEmpty(allExpectedIdList)) {
            receivableReportPage = commissionExpectedService.receivableReportPage(reportPage, allExpectedIdList);
        }

        // 组装返回结果
        ReceivableReportResponse response = new ReceivableReportResponse();
        response.setStatisticsVO(statisticsVO);
        response.setPage(receivableReportPage);
        return Result.success(response);
    }
}
