package com.fs.course.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import com.fs.common.exception.ServiceException;
import com.fs.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.company.domain.Company;
import com.fs.company.mapper.CompanyMapper;
import com.fs.company.mapper.CompanyUserMapper;
import com.fs.course.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.course.domain.FsUserCourseCompanyStatistics;
import com.fs.course.service.IFsUserCourseCompanyStatisticsService;

/**
 * 会员每日看课统计Service业务层处理
 *
 * @author fs
 * @date 2025-10-27
 */
@Service
@Slf4j
public class FsUserCourseCompanyStatisticsServiceImpl extends ServiceImpl<FsUserCourseCompanyStatisticsMapper, FsUserCourseCompanyStatistics> implements IFsUserCourseCompanyStatisticsService {
    @Autowired
    private CompanyMapper companyMapper;
    /**
     * 查询会员每日看课统计
     *
     * @param id 会员每日看课统计主键
     * @return 会员每日看课统计
     */
    @Override
    public FsUserCourseCompanyStatistics selectFsUserCourseCompanyStatisticsById(Long id)
    {
        return baseMapper.selectFsUserCourseCompanyStatisticsById(id);
    }

    /**
     * 查询会员每日看课统计列表
     *
     * @param fsUserCourseCompanyStatistics 会员每日看课统计
     * @return 会员每日看课统计
     */
    @Override
    public List<FsUserCourseCompanyStatistics> selectFsUserCourseCompanyStatisticsList(FsUserCourseCompanyStatistics fsUserCourseCompanyStatistics)
    {
        return baseMapper.selectFsUserCourseCompanyStatisticsList(fsUserCourseCompanyStatistics);
    }

    /**
     * 新增会员每日看课统计
     *
     * @param fsUserCourseCompanyStatistics 会员每日看课统计
     * @return 结果
     */
    @Override
    public int insertFsUserCourseCompanyStatistics(FsUserCourseCompanyStatistics fsUserCourseCompanyStatistics)
    {
        fsUserCourseCompanyStatistics.setCreateTime(DateUtils.getNowDate());
        return baseMapper.insertFsUserCourseCompanyStatistics(fsUserCourseCompanyStatistics);
    }

    /**
     * 修改会员每日看课统计
     *
     * @param fsUserCourseCompanyStatistics 会员每日看课统计
     * @return 结果
     */
    @Override
    public int updateFsUserCourseCompanyStatistics(FsUserCourseCompanyStatistics fsUserCourseCompanyStatistics)
    {
        fsUserCourseCompanyStatistics.setUpdateTime(DateUtils.getNowDate());
        return baseMapper.updateFsUserCourseCompanyStatistics(fsUserCourseCompanyStatistics);
    }

    /**
     * 批量删除会员每日看课统计
     *
     * @param ids 需要删除的会员每日看课统计主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseCompanyStatisticsByIds(Long[] ids)
    {
        return baseMapper.deleteFsUserCourseCompanyStatisticsByIds(ids);
    }

    /**
     * 删除会员每日看课统计信息
     *
     * @param id 会员每日看课统计主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseCompanyStatisticsById(Long id)
    {
        return baseMapper.deleteFsUserCourseCompanyStatisticsById(id);
    }
    /**
     * 会员每日统计定时任务
     * @param status
     */
    @Override
    public void courseDailyStatisticsTask(Integer status, Integer day) {
        /**
         * 课程数据统计任务
         *
         * 统计内容：
         * 1. 看课次数、完播次数、完播率（fs_course_watch_log）
         * 2. 答题数量、正确数量、正确率（fs_course_answer_logs）
         * 3. 红包领取次数、金额（fs_course_red_packet_log）
         * 4. 会员数量、黑名单数量（fs_user_company_user）
         *
         * 参数说明：
         * status=1 → 查询前一天的数据（00:00:00 ~ 23:59:59）
         * status=2 → 查询前一个整点小时的数据（例如 17:15 → 16:00:00~16:59:59）
         * status=3 → 查询最近 day 天到昨天23:59:59的数据
         */
        log.info("【课程统计任务开始】status={}, day={}", status, day);

        // 参数校验
        if (status == null || (!status.equals(1) && !status.equals(2) && !status.equals(3))) {
            log.warn("课程统计任务状态参数错误：{}", status);
            return;
        }
        if (status.equals(3) && (day == null || day <= 0)) {
            log.warn("课程统计任务参数错误：status=3 时 day 不能为空且 > 0");
            return;
        }

        try {
            // 计算时间范围
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime startTime;
            LocalDateTime endTime;

            //统计时间（创建时间）
            Date date = new Date();
            switch (status) {
                case 1:
                    // 前一天 00:00:00 ~ 23:59:59
                    LocalDate yesterday = LocalDate.now().minusDays(1);
                    startTime = yesterday.atStartOfDay();
                    endTime = yesterday.atTime(23, 59, 59);
                    date=DateUtils.addDays(new Date(),-1);
                    break;

                case 2:
                    // 前一个整点小时：例如现在17:15 → 16:00:00 - 16:59:59
                    LocalDateTime lastHour = now.truncatedTo(ChronoUnit.HOURS).minusHours(1);
                    startTime = lastHour;
                    endTime = lastHour.withMinute(59).withSecond(59);
                    break;

                case 3:
                    // 最近 day 天到昨天晚上23:59:59
                    // 结束时间：昨天23:59:59
                    LocalDate yesterdayEnd = LocalDate.now().minusDays(1);
                    endTime = yesterdayEnd.atTime(23, 59, 59);
                    date=DateUtils.addDays(new Date(),-1);
                    // 开始时间：day天前的00:00:00
                    LocalDate startDate = yesterdayEnd.minusDays(day - 1);
                    startTime = startDate.atStartOfDay();
                    break;

                default:
                    log.warn("未知状态值：{}", status);
                    return;
            }

            String start = startTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String end = endTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            log.info("【课程统计时间范围】{} - {}", start, end);

            // 查询公司列表
            List<Company> companyList = companyMapper.selectCompanyAllList();
            if (companyList == null || companyList.isEmpty()) {
                log.warn("未查询到任何公司信息，任务结束");
                return;
            }

            int total = 0;
            for (Company company : companyList) {
                try {
                    List<FsUserCourseCompanyStatistics> statisticsList =
                            baseMapper.selectStatisticsByDate(company.getCompanyId(), start, end);

                    if (statisticsList == null || statisticsList.isEmpty()) {
                        log.info("公司[{}]({}) 在时间段 {} - {} 无统计数据", company.getCompanyName(), company.getCompanyId(), start, end);
                        continue;
                    }

                    for (FsUserCourseCompanyStatistics stat : statisticsList) {
                        stat.setCompanyId(company.getCompanyId());
                        stat.setCompanyName(company.getCompanyName());
                        stat.setCreateDate(date);
                        baseMapper.insertFsUserCourseCompanyStatistics(stat);
                        total++;
                    }

                    log.info("公司[{}]({}) 数据统计完成，共 {} 条", company.getCompanyName(), company.getCompanyId(), statisticsList.size());

                } catch (Exception ex) {
                    log.error("公司[{}]({}) 统计异常：{}", company.getCompanyName(), company.getCompanyId(), ex.getMessage(), ex);
                }
            }

            log.info("【课程统计任务完成】共处理公司数={}，插入统计数据={} 条", companyList.size(), total);

        } catch (Exception e) {
            log.error("课程统计任务执行异常：{}", e.getMessage(), e);
        }
    }

    @Override
    public List<FsUserCourseCompanyStatistics> selectFsUserCourseCompanyStatisticsTotal(FsUserCourseCompanyStatistics fsUserCourseCompanyStatistics) {
        // 判断对象是否为空，或 companyId 是否为空
        Long companyId = Optional.ofNullable(fsUserCourseCompanyStatistics)
                .map(FsUserCourseCompanyStatistics::getCompanyId)
                .orElseThrow(() -> new ServiceException("请选择公司后再进行统计查询！"));

        // companyId 不为空，再执行查询
        return baseMapper.selectFsUserCourseCompanyStatisticsTotal(fsUserCourseCompanyStatistics);
    }



}
