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.BankTransactionDetailsPageReqVO;
import com.yc.ship.module.trade.controller.admin.report.vo.BankTransactionDetailsRespVO;
import com.yc.ship.module.trade.dal.mysql.report.BankTransactionDetailsMapper;
import com.yc.ship.module.trade.enums.PayTypeEnum;
import com.yc.ship.module.trade.service.report.BankTransactionDetailsService;
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 实现类
 * <p>
 * 数据来源：
 * 1. 订单支付（trade_order_pay, orderType=0, payStatus=1）
 * 2. 订单退款（trade_order_pay, refundAmount > 0）
 * 3. 充值（trade_order_pay, orderType=1）
 * 4. 账单还款（ota_bill, billStatus=1）
 * <p>
 * 性能优化：
 * - 使用 UNION ALL 在数据库层合并四类交易数据，单次 SQL 完成查询
 * - 外层包装统一过滤条件，避免多次查询内存合并
 * - 分页查询由 MyBatis-Plus IPage 自动处理
 *
 * @author auto-generated
 */
@Service
@Slf4j
public class BankTransactionDetailsServiceImpl implements BankTransactionDetailsService {

    /** 交易类型常量 */
    private static final int TRANSACTION_TYPE_PAYMENT = 1;
    private static final int TRANSACTION_TYPE_REFUND = 2;
    private static final int TRANSACTION_TYPE_RECHARGE = 3;
    private static final int TRANSACTION_TYPE_BILL_REPAYMENT = 4;

    @Resource
    private BankTransactionDetailsMapper bankTransactionDetailsMapper;

    /**
     * 查询银行流水交易明细分页
     */
    @Override
    public PageResult<BankTransactionDetailsRespVO> getBankTransactionDetailsPage(BankTransactionDetailsPageReqVO pageReqVO) {
        IPage<BankTransactionDetailsRespVO> page = bankTransactionDetailsMapper.selectBankTransactionDetailsPage(
                new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
        // 转换枚举值为中文名称
        convertEnumToName(page.getRecords());
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    /**
     * 导出银行流水交易明细 Excel
     * 数字字段导出为数字格式（通过 @NumberFormat 注解实现）
     */
    @Override
    public void exportBankTransactionDetailsExcel(BankTransactionDetailsPageReqVO pageReqVO,
                                                   HttpServletResponse response) throws IOException {
        // 1. 查询所有数据（不分页）
        List<BankTransactionDetailsRespVO> list = bankTransactionDetailsMapper.selectBankTransactionDetailsExportList(pageReqVO);
        if (CollUtil.isEmpty(list)) {
            log.warn("[exportBankTransactionDetailsExcel] 无数据可导出");
        } else {
            // 2. 转换枚举值为中文名称
            convertEnumToName(list);
            // 3. 计算合计行并追加到列表末尾
            BankTransactionDetailsRespVO summary = calculateSummary(list);
            list.add(summary);
        }
        // 4. 导出 Excel（amount 字段使用 @NumberFormat("0.00") 注解确保导出为数字格式）
        ExcelUtils.write(response, "银行流水交易明细表.xls", "银行流水交易明细", BankTransactionDetailsRespVO.class, list);
    }

    /**
     * 将枚举值转换为中文名称，便于前端展示和 Excel 导出
     */
    private void convertEnumToName(List<BankTransactionDetailsRespVO> list) {
        if (CollUtil.isEmpty(list)) {
            return;
        }
        for (BankTransactionDetailsRespVO item : list) {
            // 转换交易类型
            if (item.getTransactionType() != null) {
                switch (item.getTransactionType()) {
                    case "1":
                        item.setTransactionType("支付");
                        break;
                    case "2":
                        item.setTransactionType("退款");
                        break;
                    case "3":
                        item.setTransactionType("充值");
                        break;
                    case "4":
                        item.setTransactionType("账单还款");
                        break;
                    default:
                        break;
                }
            }
            // 转换支付方式
            if (item.getPaymentMethod() != null) {
                try {
                    int payType = Integer.parseInt(item.getPaymentMethod());
                    String payTypeName = getPayTypeName(payType);
                    item.setPaymentMethod(payTypeName);
                } catch (NumberFormatException e) {
                    // 已经是中文名称，无需转换
                }
            }
        }
    }

    /**
     * 获取支付方式名称
     */
    private String getPayTypeName(int payType) {
        for (PayTypeEnum e : PayTypeEnum.values()) {
            if (e.getType() == payType) {
                return e.getName();
            }
        }
        return "其他";
    }

    /**
     * 计算合计行数据
     */
    private BankTransactionDetailsRespVO calculateSummary(List<BankTransactionDetailsRespVO> list) {
        BankTransactionDetailsRespVO summary = new BankTransactionDetailsRespVO();
        summary.setTransactionTime("合计");
        summary.setBoardingTime("");
        summary.setOrderNo("");
        summary.setTravelAgencyName("");
        summary.setPaymentMethod("");
        summary.setTransactionType("");
        summary.setBankSerialNo("");

        BigDecimal totalAmount = BigDecimal.ZERO;
        for (BankTransactionDetailsRespVO item : list) {
            if (item.getAmount() != null) {
                totalAmount = totalAmount.add(item.getAmount());
            }
        }
        summary.setAmount(totalAmount);
        return summary;
    }

}
