package com.ylx.point.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ylx.common.core.domain.model.WxLoginUser;
import com.ylx.common.utils.SecurityUtils;
import com.ylx.point.domain.PointUserLog;
import com.ylx.point.domain.dto.UserPointDetailQueryDTO;
import com.ylx.point.domain.dto.UserPointPageDTO;
import com.ylx.point.domain.vo.UserPointInfoVO;
import com.ylx.point.domain.vo.UserPointDetailVO;
import com.ylx.point.domain.vo.UserPointLogVO;
import com.ylx.point.mapper.PointUserLogMapper;
import com.ylx.point.service.IPointActivityService;
import com.ylx.point.service.IPointUserActivityTaskCompletionService;
import com.ylx.point.service.IPointUserLogService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;

/**
 * 用户积分流水Service业务层处理
 *
 * @author wzj
 * @date 2026-03-25
 */
@Service
public class PointUserLogServiceImpl extends ServiceImpl<PointUserLogMapper, PointUserLog> implements IPointUserLogService {

    @Resource
    private PointUserLogMapper pointUserLogMapper;
    @Resource
    private IPointUserActivityTaskCompletionService pointUserActivityTaskCompletionService;
    @Resource
    private IPointActivityService pointActivityService;

    @Override
    public UserPointInfoVO getUserPointInfo(String cityCode) {

        // 当前登录用户信息
        WxLoginUser wxLoginUser = SecurityUtils.getWxLoginUser();
        if (ObjectUtil.isNull(wxLoginUser)) {
            throw new RuntimeException("用户未登录");
        }
        String openId = wxLoginUser.getCOpenid();

        UserPointInfoVO vo = new UserPointInfoVO();

        // 1. 准备时间参数
        String currentMonth = DateUtil.format(DateUtil.date(), "yyyyMM");
        // 本月第一天 00:00:00
        String startOfThisMonth = DateUtil.beginOfMonth(DateUtil.date()).toString();
        // 本月最后一天 23:59:59
        String endOfThisMonth = DateUtil.endOfMonth(DateUtil.date()).toString();
        // 2. 查询积分相关数据 (Total, Earned, Expire)

        // A. 查询积分统计 (Total, Earned, Expire)
        Map<String, Object> pointStats = pointUserLogMapper.selectPointStatistics(openId, currentMonth, startOfThisMonth, endOfThisMonth);

        // B. 查询已完成任务数
        Integer completedCount = pointUserActivityTaskCompletionService.selectCompletedTaskCount(openId);

        // C. 查询系统总任务数
        Integer totalTasks = pointActivityService.selectTotalActiveTasks(cityCode);

        if (pointStats != null) {
            // 数据库返回的是 BigInteger 或 Long，需要转为 BigDecimal
            vo.setTotalPoints(new BigDecimal(pointStats.get("totalPoints").toString()));
            vo.setEarnedPoints(new BigDecimal(pointStats.get("earnedPoints").toString()));
            vo.setExpirePoints(new BigDecimal(pointStats.get("expirePoints").toString()));
        } else {
            vo.setTotalPoints(BigDecimal.ZERO);
            vo.setEarnedPoints(BigDecimal.ZERO);
            vo.setExpirePoints(BigDecimal.ZERO);
        }

        // 任务数据
        int completed = (completedCount != null) ? completedCount : 0;
        vo.setCompletedTask(completed);

        int pending = (totalTasks != null ? totalTasks : 0) - completed;
        vo.setPendingTasks(Math.max(pending, 0)); // 防止出现负数

        return vo;
    }

    @Override
    public Page<UserPointLogVO> getUserPointLogList(Page<PointUserLog> page, UserPointPageDTO dto) {

        // 当前登录用户信息
        WxLoginUser wxLoginUser = SecurityUtils.getWxLoginUser();

        if (ObjectUtil.isNull(wxLoginUser)) {
            throw new RuntimeException("用户未登录");
        }
        dto.setOpenId(wxLoginUser.getCOpenid());

        Page<UserPointLogVO> pageData = this.pointUserLogMapper.getUserPointLogList(page, dto);

        return pageData;
    }

    @Override
    public Page<UserPointDetailVO> getPcUserPointDetailList(Page<UserPointDetailVO> page, UserPointDetailQueryDTO dto) {
        normalizeTimeRange(dto);
        return this.pointUserLogMapper.selectPcUserPointDetailList(page, dto);
    }

    /**
     * 格式化时间范围
     * @param dto
     */
    private void normalizeTimeRange(UserPointDetailQueryDTO dto) {
        if (StringUtils.isNotBlank(dto.getStartTime()) && dto.getStartTime().trim().length() == 10) {
            dto.setStartTime(dto.getStartTime().trim() + " 00:00:00");
        }
        if (StringUtils.isNotBlank(dto.getEndTime()) && dto.getEndTime().trim().length() == 10) {
            dto.setEndTime(dto.getEndTime().trim() + " 23:59:59");
        }
    }

}
