package com.sundot.airport.attendance.portrait;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.attendance.domain.portrait.StationDeptWorkStats;
import com.sundot.airport.attendance.domain.portrait.WorkDateStats;
import com.sundot.airport.attendance.domain.portrait.WorkHoursStats;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.domain.portrait.IndicatorCalculateParams;
import com.sundot.airport.common.domain.portrait.ModularIndicatorResult;
import com.sundot.airport.common.enums.DeptTypeEnum;
import com.sundot.airport.common.enums.RoleTypeEnum;
import com.sundot.airport.common.enums.portrait.UserType;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.system.service.ISysUserService;
import com.sundot.airport.system.service.portrait.UserPortraitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 站级工作统计服务
 * 专门处理考勤模块中站级部门的特殊统计逻辑
 */
@Service
public class StationWorkStatsService {


    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private UserPortraitService userPortraitService;

    @Autowired
    private ISysUserService iSysUserService;

    /**
     * 计算站级部门及其下属部门的工作统计数据
     *
     * @param params 指定部门
     * @return 工作统计数据列表
     */
    public List<StationDeptWorkStats> calculateStationWorkStats(IndicatorCalculateParams params) {
        Long stationId = params.getDeptId();
        if (stationId == null) {
            return null;
        }

        // 直接查询部门信息
        SysDept queryDept = new SysDept();
        queryDept.setDeptId(stationId);
        queryDept.setDeptType(DeptTypeEnum.BRIGADE.getCode());
        List<SysDept> sysDeptList = sysDeptService.selectDeptInfo(queryDept);

        if (CollectionUtil.isEmpty(sysDeptList)) {
            return null;
        }
        IndicatorCalculateParams indicatorCalculateParams = this.appendParams(params);
        // 为每个部门生成统计信息
        return sysDeptList.stream()
                .map(dept -> getStationDeptWorkStats(dept, indicatorCalculateParams))
                .filter(java.util.Objects::nonNull)
                .collect(Collectors.toList());
    }

    private IndicatorCalculateParams appendParams(IndicatorCalculateParams dto) {
        IndicatorCalculateParams params = new IndicatorCalculateParams();
        params.setIndicatorTypes(Arrays.asList("qualificationLevel", "workingDate", "workingHours", "effectiveSeizureCount", "workYears", "securityWorkYears"));
        // 设置默认时间范围
        java.util.Date endTime = Optional.ofNullable(dto.getEndTime()).orElse(new java.util.Date());
        java.util.Date startTime = Optional.ofNullable(dto.getStartTime())
                .orElse(java.util.Date.from(endTime.toInstant().minusSeconds(7862400L))); // 91天

        params.setStartTime(startTime);
        params.setEndTime(endTime);
        return params;
    }

    /**
     * 为特定部门生成工作统计信息
     *
     * @param dept 部门信息
     * @return 部门工作统计信息
     */
    private StationDeptWorkStats getStationDeptWorkStats(SysDept dept, IndicatorCalculateParams indicatorCalculateParams) {
        if (dept == null) {
            return null;
        }

        StationDeptWorkStats stationStats = new StationDeptWorkStats();
        stationStats.setDimension(dept.getDeptName());
        stationStats.setDeptId(dept.getDeptId());
        stationStats.setDeptName(dept.getDeptName());

        indicatorCalculateParams.setUserType(StrUtil.equals(DeptTypeEnum.STATION.getCode(), dept.getDeptType()) ? UserType.STATION : UserType.BRIGADE);


        //获取指标
        indicatorCalculateParams.setDeptId(dept.getDeptId());
        List<SysUser> sysUsers = iSysUserService.selectUserListByRoleKeyAndDeptId(Arrays.asList(RoleTypeEnum.banzuzhang.getCode(), RoleTypeEnum.SecurityCheck.getCode()), dept.getDeptId());
        indicatorCalculateParams.setUserIds(sysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList()));
        // 计算人均出勤天数
        stationStats.setAvgWorkingDays(avgWorkingDays(indicatorCalculateParams));

        // 计算人均上岗时长
        stationStats.setAvgWorkingHours(avgWorkingHours(indicatorCalculateParams));

        return stationStats;
    }


    private BigDecimal avgWorkingDays(IndicatorCalculateParams params) {
        BigDecimal avgWorkingDays = BigDecimal.ZERO;
        ModularIndicatorResult indicators = userPortraitService.getIndicators(params, Arrays.asList("attendance"));
        if (indicators == null) {
            return avgWorkingDays;
        }

        AttendanceModuleIndicatorResult attendanceResult = (AttendanceModuleIndicatorResult) indicators.getModuleResult("attendance");
        if (attendanceResult == null) {
            return avgWorkingDays;
        }

        Object workingDate = attendanceResult.getWorkingDate();
        if (workingDate instanceof WorkDateStats) {
            WorkDateStats workDateStats = (WorkDateStats) workingDate;
            avgWorkingDays = workDateStats.getAveragePersonnel() != null ?
                    workDateStats.getAveragePersonnel() : BigDecimal.ZERO;
        }
        return avgWorkingDays;
    }


    private BigDecimal avgWorkingHours(IndicatorCalculateParams params) {
        BigDecimal avgWorkingHours = BigDecimal.ZERO;
        ModularIndicatorResult indicators = userPortraitService.getIndicators(params, Arrays.asList("attendance"));
        if (indicators == null) {
            return avgWorkingHours;
        }

        AttendanceModuleIndicatorResult attendanceResult = (AttendanceModuleIndicatorResult) indicators.getModuleResult("attendance");
        if (attendanceResult == null) {
            return avgWorkingHours;
        }
        Object workingHours = attendanceResult.getWorkingHours();
        if (workingHours instanceof WorkHoursStats) {
            WorkHoursStats workHoursStats = (WorkHoursStats) workingHours;
            avgWorkingHours = workHoursStats.getAveragePersonnel() != null ?
                    workHoursStats.getAveragePersonnel() : BigDecimal.ZERO;
        }

        return avgWorkingHours;
    }

}