package shop.alien.lawyer.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import shop.alien.entity.result.R;
import shop.alien.entity.store.vo.LawyerOrderStatisticsVO;
import shop.alien.lawyer.service.LawyerStatisticsService;
import shop.alien.mapper.LawyerConsultationOrderMapper;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Map;

/**
 * 律师统计 服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LawyerStatisticsServiceImpl implements LawyerStatisticsService {

    private final LawyerConsultationOrderMapper lawyerConsultationOrderMapper;

    /**
     * 金额单位转换：分转元
     */
    private static final int FEN_TO_YUAN = 100;

    /**
     * 日期时间格式
     */
    private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

    /**
     * 默认小数位数
     */
    private static final int DECIMAL_SCALE = 2;

    /**
     * Map key：订单数量
     */
    private static final String KEY_ORDER_COUNT = "orderCount";

    /**
     * Map key：总金额
     */
    private static final String KEY_TOTAL_AMOUNT = "totalAmount";

    /**
     * Map key：本月订单量
     */
    private static final String KEY_MONTH_ORDER_COUNT = "monthOrderCount";

    /**
     * Map key：本月收益
     */
    private static final String KEY_MONTH_REVENUE = "monthRevenue";

    /**
     * Map key：总订单量
     */
    private static final String KEY_TOTAL_ORDER_COUNT = "totalOrderCount";

    /**
     * Map key：总收益
     */
    private static final String KEY_TOTAL_REVENUE = "totalRevenue";

    /**
     * 日期格式化器
     */
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_TIME_PATTERN);

    @Override
    public R<LawyerOrderStatisticsVO> getOrderStatistics(Integer lawyerUserId) {
        log.info("获取律师订单统计数据开始，lawyerUserId={}", lawyerUserId);

        // 参数校验
        if (lawyerUserId == null || lawyerUserId <= 0) {
            log.warn("获取律师订单统计数据失败：律师用户ID为空或无效，lawyerUserId={}", lawyerUserId);
            return R.fail("律师用户ID不能为空");
        }

        try {
            LawyerOrderStatisticsVO statistics = new LawyerOrderStatisticsVO();

            // 统计本月数据
            buildMonthStatistics(statistics, lawyerUserId);

            // 统计总数据
            buildTotalStatistics(statistics, lawyerUserId);

            // 统计进行中订单
            statistics.setInProgressOrder(buildOrderStatusStatistics(
                    lawyerConsultationOrderMapper.getInProgressStatistics(lawyerUserId)));

            // 统计待接单订单
            statistics.setPendingAcceptOrder(buildOrderStatusStatistics(
                    lawyerConsultationOrderMapper.getPendingAcceptStatistics(lawyerUserId)));

            // 统计已退款订单
            statistics.setRefundedOrder(buildOrderStatusStatistics(
                    lawyerConsultationOrderMapper.getRefundedStatistics(lawyerUserId)));

            log.info("获取律师订单统计数据成功，lawyerUserId={}, monthOrderCount={}, monthRevenue={}, "
                            + "totalOrderCount={}, totalRevenue={}",
                    lawyerUserId, statistics.getMonthOrderCount(), statistics.getMonthRevenue(),
                    statistics.getTotalOrderCount(), statistics.getTotalRevenue());

            return R.data(statistics);
        } catch (RuntimeException e) {
            log.error("获取律师订单统计数据异常，lawyerUserId={}", lawyerUserId, e);
            return R.fail("获取统计数据失败：" + e.getMessage());
        }
    }

    /**
     * 构建本月统计数据
     *
     * @param statistics  统计对象
     * @param lawyerUserId 律师用户ID
     */
    private void buildMonthStatistics(LawyerOrderStatisticsVO statistics, Integer lawyerUserId) {
        String[] timeRange = getCurrentMonthTimeRange();
        Map<String, Object> monthStats = lawyerConsultationOrderMapper.getMonthStatistics(
                lawyerUserId, timeRange[0], timeRange[1]);

        if (monthStats != null) {
            statistics.setMonthOrderCount(getIntegerValue(monthStats.get(KEY_MONTH_ORDER_COUNT)));
            Long monthRevenueFen = getLongValue(monthStats.get(KEY_MONTH_REVENUE));
            statistics.setMonthRevenue(convertFenToYuan(monthRevenueFen));
        } else {
            statistics.setMonthOrderCount(0);
            statistics.setMonthRevenue(BigDecimal.ZERO);
        }
    }

    /**
     * 构建总统计数据
     *
     * @param statistics  统计对象
     * @param lawyerUserId 律师用户ID
     */
    private void buildTotalStatistics(LawyerOrderStatisticsVO statistics, Integer lawyerUserId) {
        Map<String, Object> totalStats = lawyerConsultationOrderMapper.getTotalStatistics(lawyerUserId);

        if (totalStats != null) {
            statistics.setTotalOrderCount(getIntegerValue(totalStats.get(KEY_TOTAL_ORDER_COUNT)));
            Long totalRevenueFen = getLongValue(totalStats.get(KEY_TOTAL_REVENUE));
            statistics.setTotalRevenue(convertFenToYuan(totalRevenueFen));
        } else {
            statistics.setTotalOrderCount(0);
            statistics.setTotalRevenue(BigDecimal.ZERO);
        }
    }

    /**
     * 构建订单状态统计数据
     *
     * @param statsMap 统计数据Map
     * @return 订单状态统计对象
     */
    private LawyerOrderStatisticsVO.OrderStatusStatistics buildOrderStatusStatistics(
            Map<String, Object> statsMap) {
        LawyerOrderStatisticsVO.OrderStatusStatistics orderStatusStatistics =
                new LawyerOrderStatisticsVO.OrderStatusStatistics();

        if (statsMap != null) {
            orderStatusStatistics.setOrderCount(getIntegerValue(statsMap.get(KEY_ORDER_COUNT)));
            Long amountFen = getLongValue(statsMap.get(KEY_TOTAL_AMOUNT));
            orderStatusStatistics.setTotalAmount(convertFenToYuan(amountFen));
        } else {
            orderStatusStatistics.setOrderCount(0);
            orderStatusStatistics.setTotalAmount(BigDecimal.ZERO);
        }

        return orderStatusStatistics;
    }

    /**
     * 获取当前月份的时间范围
     *
     * @return 时间范围数组，[0]为开始时间，[1]为结束时间
     */
    private String[] getCurrentMonthTimeRange() {
        LocalDate now = LocalDate.now();
        LocalDate firstDayOfMonth = now.with(TemporalAdjusters.firstDayOfMonth());
        LocalDate firstDayOfNextMonth = now.with(TemporalAdjusters.firstDayOfNextMonth());
        LocalDateTime startDateTime = firstDayOfMonth.atStartOfDay();
        LocalDateTime endDateTime = firstDayOfNextMonth.atStartOfDay();

        return new String[]{
                startDateTime.format(DATE_TIME_FORMATTER),
                endDateTime.format(DATE_TIME_FORMATTER)
        };
    }

    /**
     * 将分转换为元（保留2位小数）
     *
     * @param fen 分，单位：分
     * @return 元，单位：元，保留2位小数
     */
    private BigDecimal convertFenToYuan(Long fen) {
        if (fen == null || fen == 0) {
            return BigDecimal.ZERO;
        }
        return BigDecimal.valueOf(fen)
                .divide(BigDecimal.valueOf(FEN_TO_YUAN), DECIMAL_SCALE, RoundingMode.HALF_UP);
    }

    /**
     * 从Map中获取Integer值
     * <p>
     * 支持Integer、Long、Number类型的转换
     * </p>
     *
     * @param value 对象值，可能为Integer、Long或其他Number类型
     * @return Integer值，如果value为null或无法转换则返回0
     */
    private Integer getIntegerValue(Object value) {
        if (value == null) {
            return 0;
        }
        if (value instanceof Integer) {
            return (Integer) value;
        }
        if (value instanceof Long) {
            return ((Long) value).intValue();
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        log.warn("无法将对象转换为Integer，value={}, type={}", value, value.getClass().getName());
        return 0;
    }

    /**
     * 从Map中获取Long值
     * <p>
     * 支持Long、Integer、Number类型的转换
     * </p>
     *
     * @param value 对象值，可能为Long、Integer或其他Number类型
     * @return Long值，如果value为null或无法转换则返回0L
     */
    private Long getLongValue(Object value) {
        if (value == null) {
            return 0L;
        }
        if (value instanceof Long) {
            return (Long) value;
        }
        if (value instanceof Integer) {
            return ((Integer) value).longValue();
        }
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        log.warn("无法将对象转换为Long，value={}, type={}", value, value.getClass().getName());
        return 0L;
    }
}

