package com.sundot.airport.web.controller.system;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.attendance.domain.AttendanceRecord;
import com.sundot.airport.attendance.service.IAttendanceRecordService;
import com.sundot.airport.check.service.ICheckLargeScreenService;
import com.sundot.airport.common.core.controller.BaseController;
import com.sundot.airport.common.core.domain.AjaxResult;
import com.sundot.airport.common.core.domain.BaseLargeScreenQueryParamDto;
import com.sundot.airport.common.core.domain.SysUsageReportDto;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.dto.BaseCommonDto;
import com.sundot.airport.common.dto.QuizAccuracyAnalysisResultDto;
import com.sundot.airport.common.enums.DeptTypeEnum;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.common.utils.DeptUtils;
import com.sundot.airport.exam.dto.DashboardOverviewDTO;
import com.sundot.airport.exam.dto.DashboardQueryDTO;
import com.sundot.airport.exam.dto.DashboardUserRankingDTO;
import com.sundot.airport.exam.service.IAccuracyStatisticsService;
import com.sundot.airport.exam.service.IDashboardService;
import com.sundot.airport.item.service.ItemLargeScreenService;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 使用报告
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/system/usageReport")
public class SysUsageReportController extends BaseController {

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ICheckLargeScreenService checkLargeScreenService;

    @Autowired
    private ItemLargeScreenService itemLargeScreenService;

    @Autowired
    private IAttendanceRecordService attendanceRecordService;

    @Autowired
    private IDashboardService dashboardService;

    @Autowired
    private IAccuracyStatisticsService accuracyStatisticsService;

    /**
     * 使用报告
     */
    @GetMapping("/report")
    public AjaxResult checkAnalysisReportCheckProblemDistributionDto(BaseLargeScreenQueryParamDto paramDto) {
        SysUsageReportDto result = getSysUsageReportDto(paramDto);
        return success(result);
    }

    /**
     * 获取使用报告
     */
    private SysUsageReportDto getSysUsageReportDto(BaseLargeScreenQueryParamDto paramDto) {
        if (ObjectUtil.isNull(paramDto.getStartDate()) || ObjectUtil.isNull(paramDto.getEndDate())) {
            Date lastMonday = getLastWeekMonday();
            Date lastSunday = getLastWeekSunday();
            paramDto.setStartDate(lastMonday);
            paramDto.setEndDate(lastSunday);
        }
        SysUsageReportDto result = new SysUsageReportDto();
        result.setStartDate(paramDto.getStartDate());
        result.setEndDate(paramDto.getEndDate());
        result.setBasicSituation(getBasicSituation(paramDto));
        result.setRunSituation(getRunSituation(paramDto));
        return result;
    }

    /**
     * 获取上周周一的日期 (java.util.Date)
     */
    public static Date getLastWeekMonday() {
        LocalDate today = LocalDate.now();
        // 计算本周周一（ISO标准：周一为1，周日为7）
        LocalDate mondayThisWeek = today.with(DayOfWeek.MONDAY);
        // 上周周一 = 本周周一 - 7天
        LocalDate lastMonday = mondayThisWeek.minusWeeks(1);

        return convertToUtilDate(lastMonday);
    }

    /**
     * 获取上周周日的日期 (java.util.Date)
     */
    public static Date getLastWeekSunday() {
        LocalDate today = LocalDate.now();
        // 计算本周周一
        LocalDate mondayThisWeek = today.with(DayOfWeek.MONDAY);
        // 上周周日 = 本周周一 - 1天
        LocalDate lastSunday = mondayThisWeek.minusDays(1);

        return convertToUtilDate(lastSunday);
    }

    /**
     * 将LocalDate转换为java.util.Date
     */
    private static Date convertToUtilDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取基本情况
     */
    private SysUsageReportDto.BasicSituation getBasicSituation(BaseLargeScreenQueryParamDto paramDto) {
        SysUsageReportDto.BasicSituation basicSituation = new SysUsageReportDto.BasicSituation();
        List<SysUsageReportDto.SysDeptInfo> sysDeptInfoList = new ArrayList<>();
        // 获取当前用户所在站点ID
        Long topSiteId = DeptUtils.getTopSiteId(sysDeptService.selectDeptById(getDeptId()));
        if (ObjectUtil.isNull(topSiteId)) {
            throw new ServiceException("无法找到有效的站点信息");
        }
        List<SysDept> deptList = sysDeptService.selectChildrenDeptById(topSiteId);
        deptList = deptList.stream().filter(item -> StrUtil.equals(DeptTypeEnum.BRIGADE.getCode(), item.getDeptType())).collect(Collectors.toList());
        deptList.forEach(item -> {
            SysUsageReportDto.SysDeptInfo sysDeptInfo = new SysUsageReportDto.SysDeptInfo();
            List<SysUser> sysUserList = sysUserService.selectUserByDeptId(item.getDeptId());
//            List<SysUser> sysUserList = sysUserService.selectUserListByRoleKeyAndDeptId(Arrays.asList(RoleTypeEnum.banzuzhang.getCode(), RoleTypeEnum.SecurityCheck.getCode()), item.getId());
            sysDeptInfo.setDeptId(item.getDeptId());
            sysDeptInfo.setDeptName(item.getDeptName());
            sysDeptInfo.setPeopleNumber(sysUserList.size());
            sysDeptInfoList.add(sysDeptInfo);
        });
        basicSituation.setSysDeptInfoList(sysDeptInfoList);
        basicSituation.setSysDeptInfoListDesc(sysDeptInfoList.stream().map(SysUsageReportDto.SysDeptInfo::getDeptName).collect(Collectors.joining("、")));
        basicSituation.setTotalPeopleNumber(sysDeptInfoList.stream().mapToInt(SysUsageReportDto.SysDeptInfo::getPeopleNumber).sum());
        return basicSituation;
    }

    /**
     * 获取运行情况
     */
    private SysUsageReportDto.RunSituation getRunSituation(BaseLargeScreenQueryParamDto paramDto) {
        SysUsageReportDto.RunSituation runSituation = new SysUsageReportDto.RunSituation();
        runSituation.setAttendanceModule(getAttendanceModule(paramDto));
        runSituation.setSeizureModule(getSeizureModule(paramDto));
        runSituation.setExamModule(getExamModule(paramDto));
        runSituation.setCheckModule(getCheckModule(paramDto));
        return runSituation;
    }

    /**
     * 获取勤务模块
     */
    private SysUsageReportDto.AttendanceModule getAttendanceModule(BaseLargeScreenQueryParamDto paramDto) {
        SysUsageReportDto.AttendanceModule attendanceModule = new SysUsageReportDto.AttendanceModule();
        AttendanceRecord attendanceRecordReq = new AttendanceRecord();
        attendanceRecordReq.setAttendanceDateStart(paramDto.getStartDate());
        attendanceRecordReq.setAttendanceDateEnd(paramDto.getEndDate());
        List<AttendanceRecord> attendanceRecordList = attendanceRecordService.selectAttendanceRecordList(attendanceRecordReq);
        if (CollUtil.isEmpty(attendanceRecordList)) {
            return null;
        }
        List<SysUsageReportDto.SysDeptInfo> sysDeptInfoList = new ArrayList<>();
        attendanceRecordList.stream().filter(item -> StrUtil.isNotBlank(item.getBrigadeCode())).collect(Collectors.groupingBy(item -> item.getBrigadeCode() + "_" + item.getBrigadeName())).forEach((key, value) -> {
            SysUsageReportDto.SysDeptInfo sysDeptInfo = new SysUsageReportDto.SysDeptInfo();
            sysDeptInfo.setDeptId(Long.valueOf(key.split("_")[0]));
            sysDeptInfo.setDeptName(key.split("_")[1]);
            sysDeptInfo.setPeopleNumber((int) value.stream().map(AttendanceRecord::getUserId).distinct().count());
            sysDeptInfoList.add(sysDeptInfo);
        });
        attendanceModule.setSysDeptInfoList(sysDeptInfoList);
        attendanceModule.setSysDeptInfoListDesc(sysDeptInfoList.stream().map(item -> item.getDeptName() + item.getPeopleNumber() + "人").collect(Collectors.joining("、")));
        attendanceModule.setTotalPeopleNumber(sysDeptInfoList.stream().mapToInt(SysUsageReportDto.SysDeptInfo::getPeopleNumber).sum());
        return attendanceModule;
    }

    /**
     * 获取查获模块
     */
    private SysUsageReportDto.SeizureModule getSeizureModule(BaseLargeScreenQueryParamDto paramDto) {
        SysUsageReportDto.SeizureModule seizureModule = itemLargeScreenService.getSeizureModule(paramDto);
        return seizureModule;
    }

    /**
     * 获取抽问抽答模块
     */
    private SysUsageReportDto.ExamModule getExamModule(BaseLargeScreenQueryParamDto paramDto) {
        SysUsageReportDto.ExamModule examModule = new SysUsageReportDto.ExamModule();

        String startDateStr = DateUtil.format(paramDto.getStartDate(), DatePattern.NORM_DATE_PATTERN);
        String endDateStr = DateUtil.format(paramDto.getEndDate(), DatePattern.NORM_DATE_PATTERN);

        DashboardQueryDTO query = new DashboardQueryDTO();
        query.setStartDate(startDateStr);
        query.setEndDate(endDateStr);
        query.setTimeRange("custom");

        // 总项数、平均分
        DashboardOverviewDTO overview = dashboardService.getOverview(query);
        if (overview != null) {
            examModule.setTotalItem(overview.getCompletedTasks() != null ? overview.getCompletedTasks().intValue() : 0);
            examModule.setAverageScore(overview.getAvgScore() != null ? BigDecimal.valueOf(overview.getAvgScore()) : BigDecimal.ZERO);
        }

        // 参与人数（有完成任务的用户数）
        List<DashboardUserRankingDTO> allUsers = dashboardService.getAllUsersRanking(query);
        if (CollUtil.isNotEmpty(allUsers)) {
            long participantCount = allUsers.stream()
                    .filter(user -> user.getCompletedTasks() != null && user.getCompletedTasks() > 0)
                    .count();
            examModule.setTotalPeopleNumber((int) participantCount);
        } else {
            examModule.setTotalPeopleNumber(0);
        }

        // 各分类正确率列表
        QuizAccuracyAnalysisResultDto accuracyAnalysis = accuracyStatisticsService.getQuizAccuracyAnalysis(startDateStr, endDateStr);
        if (accuracyAnalysis != null && CollUtil.isNotEmpty(accuracyAnalysis.getCategoryList())) {
            List<BaseCommonDto> typeList = accuracyAnalysis.getCategoryList().stream().map(item -> {
                BaseCommonDto dto = new BaseCommonDto();
                dto.setName(item.getCategoryName());
                dto.setScale(item.getCorrectRate());
                dto.setRemark(item.getLabel());
                return dto;
            }).collect(Collectors.toList());
            examModule.setTypeList(typeList);
        }

        return examModule;
    }

    /**
     * 获取巡检模块
     */
    private SysUsageReportDto.CheckModule getCheckModule(BaseLargeScreenQueryParamDto paramDto) {
        SysUsageReportDto.CheckModule checkModule = checkLargeScreenService.getCheckModule(paramDto);
        return checkModule;
    }

}
