package com.yc.ship.module.trade.service.report.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.excel.core.util.ExcelUtils;
import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerPageReqVO;
import com.yc.ship.module.trade.controller.admin.report.vo.IncomeOrderLedgerRespVO;
import com.yc.ship.module.trade.dal.mysql.report.IncomeOrderLedgerMapper;
import com.yc.ship.module.trade.service.report.IncomeOrderLedgerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

/**
 * 订单收入台账 Service 实现类
 *
 * @author 管理员
 */
@Service
@Slf4j
public class IncomeOrderLedgerServiceImpl implements IncomeOrderLedgerService {

    @Resource
    private IncomeOrderLedgerMapper incomeOrderLedgerMapper;

    /**
     * 查询订单收入台账分页
     *
     * @param pageReqVO 分页查询条件
     * @return 分页结果
     */
    @Override
    public PageResult<IncomeOrderLedgerRespVO> getIncomeOrderLedgerPage(IncomeOrderLedgerPageReqVO pageReqVO) {
        IPage<IncomeOrderLedgerRespVO> page = incomeOrderLedgerMapper.selectIncomeOrderLedgerPage(
                new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    /**
     * 导出订单收入台账 Excel
     *
     * @param pageReqVO 查询条件
     * @param response  HTTP响应
     * @throws IOException IO异常
     */
    @Override
    public void exportIncomeOrderLedgerExcel(IncomeOrderLedgerPageReqVO pageReqVO,
                                             HttpServletResponse response) throws IOException {
        // 1. 查询所有数据（不分页）
        List<IncomeOrderLedgerRespVO> list = incomeOrderLedgerMapper.selectIncomeOrderLedgerExportList(pageReqVO);
        if (CollUtil.isEmpty(list)) {
            log.warn("[exportIncomeOrderLedgerExcel] 无数据可导出");
        } else {
            // 2. 计算合计行并追加到列表末尾
            IncomeOrderLedgerRespVO summary = calculateSummary(list);
            list.add(summary);
        }
        // 3. 导出 Excel（数字字段使用 @NumberFormat 注解确保导出为数字格式）
        ExcelUtils.write(response, "订单收入台账.xls", "订单收入台账", IncomeOrderLedgerRespVO.class, list);
    }

    /**
     * 计算合计行数据
     */
    private IncomeOrderLedgerRespVO calculateSummary(List<IncomeOrderLedgerRespVO> list) {
        IncomeOrderLedgerRespVO summary = new IncomeOrderLedgerRespVO();
        summary.setOrderNo("合计");
        summary.setSailTime(null);
        summary.setTravelAgency(null);
        summary.setVoyage(null);
        summary.setRouteName(null);
        summary.setRoomTypeName(null);

        BigDecimal totalMarketingPrice = BigDecimal.ZERO;
        BigDecimal totalDiscountAmount = BigDecimal.ZERO;
        BigDecimal totalRefundFee = BigDecimal.ZERO;
        BigDecimal totalActualSettlementPrice = BigDecimal.ZERO;
        int totalRoomCount = 0;
        int totalAdultCount = 0;
        int totalChildCount = 0;
        int totalInfantCount = 0;
        int totalCompanionCount = 0;
        int totalFreeCount = 0;
        int totalCountSum = 0;
        int leaderCount = 0;

        for (IncomeOrderLedgerRespVO item : list) {
            totalRoomCount += item.getRoomCount() != null ? item.getRoomCount() : 0;
            totalAdultCount += item.getAdultCount() != null ? item.getAdultCount() : 0;
            totalChildCount += item.getChildCount() != null ? item.getChildCount() : 0;
            totalInfantCount += item.getInfantCount() != null ? item.getInfantCount() : 0;
            totalCompanionCount += item.getCompanionCount() != null ? item.getCompanionCount() : 0;
            leaderCount += item.getLeaderCount() != null ? item.getLeaderCount() : 0;
            totalFreeCount += item.getFreeCount() != null ? item.getFreeCount() : 0;
            totalCountSum += item.getTotalCount() != null ? item.getTotalCount() : 0;
            totalMarketingPrice = totalMarketingPrice.add(
                    item.getMarketingPrice() != null ? item.getMarketingPrice() : BigDecimal.ZERO);
            totalDiscountAmount = totalDiscountAmount.add(
                    item.getDiscountAmount() != null ? item.getDiscountAmount() : BigDecimal.ZERO);
            totalRefundFee = totalRefundFee.add(
                    item.getRefundFee() != null ? item.getRefundFee() : BigDecimal.ZERO);
            totalActualSettlementPrice = totalActualSettlementPrice.add(
                    item.getActualSettlementPrice() != null ? item.getActualSettlementPrice() : BigDecimal.ZERO);
        }

        summary.setRoomCount(totalRoomCount);
        summary.setAdultCount(totalAdultCount);
        summary.setChildCount(totalChildCount);
        summary.setInfantCount(totalInfantCount);
        summary.setCompanionCount(totalCompanionCount);
        summary.setLeaderCount(leaderCount);
        summary.setFreeCount(totalFreeCount);
        summary.setTotalCount(totalCountSum);
        summary.setMarketingPrice(totalMarketingPrice);
        summary.setDiscountAmount(totalDiscountAmount);
        summary.setRefundFee(totalRefundFee);
        summary.setActualSettlementPrice(totalActualSettlementPrice);
        return summary;
    }

}
