package com.sundot.airport.ledger.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.dto.LedgerCommonQueryReqVO;
import com.sundot.airport.common.enums.DeptTypeEnum;
import com.sundot.airport.common.enums.LedgerAlertLevelEnum;
import com.sundot.airport.common.enums.LedgerStatusLabelEnum;
import com.sundot.airport.common.enums.ScoreLevelEnum;
import com.sundot.airport.common.utils.DeptUtils;
import com.sundot.airport.common.utils.SecurityUtils;
import com.sundot.airport.ledger.domain.ScoreEvent;
import com.sundot.airport.ledger.domain.ScoreIndicator;
import com.sundot.airport.ledger.domain.vo.LedgerWarningDetailItemVO;
import com.sundot.airport.ledger.domain.vo.LedgerWarningDetailVO;
import com.sundot.airport.ledger.domain.vo.LedgerWarningVO;
import com.sundot.airport.ledger.mapper.LedgerWarningMapper;
import com.sundot.airport.ledger.service.IEmployeePortraitService;
import com.sundot.airport.ledger.service.ILedgerWarningService;
import com.sundot.airport.ledger.service.IScoreIndicatorService;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 预警页面服务
 */
@Service
public class LedgerWarningServiceImpl implements ILedgerWarningService {

    @Autowired
    private LedgerWarningMapper ledgerWarningMapper;

    @Autowired
    private IEmployeePortraitService employeePortraitService;

    @Autowired
    private IScoreIndicatorService scoreIndicatorService;

    @Autowired
    private ISysDeptService sysDeptService;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 台账数据
     */
    @Override
    public LedgerWarningVO ledger(LedgerCommonQueryReqVO queryReq) {
        LedgerWarningVO result = new LedgerWarningVO();
        result.setLedgerSupervisionProblem(ledgerWarningMapper.selectLedgerSupervisionProblem(queryReq));
        result.setLedgerRealtimeInterception(ledgerWarningMapper.selectLedgerRealtimeInterception(queryReq));
        result.setLedgerUnsafeEvent(ledgerWarningMapper.selectLedgerUnsafeEvent(queryReq));
        result.setLedgerSecurityTest(ledgerWarningMapper.selectLedgerSecurityTest(queryReq));
        result.setLedgerComplaint(ledgerWarningMapper.selectLedgerComplaint(queryReq));
        result.setLedgerServicePatrol(ledgerWarningMapper.selectLedgerServicePatrol(queryReq));
        result.setLedgerTerminalBonus(ledgerWarningMapper.selectLedgerTerminalBonus(queryReq));
        result.setLedgerRewardApproval(ledgerWarningMapper.selectLedgerRewardApproval(queryReq));
        result.setLedgerExamScore(ledgerWarningMapper.selectLedgerExamScore(queryReq));
        return result;
    }

    /**
     * 台账数据
     */
    @Override
    public LedgerWarningDetailVO ledgerDetail(LedgerCommonQueryReqVO queryReq) {
        List<String> scoreIndicatorNameList = Arrays.asList("员工规范化操作", "后台实时质控拦截", "不安全事件", "安保测试未通过", "旅客服务投诉", "服务监察", "典型服务案例", "典型案例查获", "考试成绩");
        Map<String, String> unitMap = new HashMap<>();
        unitMap.put("员工规范化操作", "项");
        unitMap.put("后台实时质控拦截", "次");
        unitMap.put("不安全事件", "起");
        unitMap.put("安保测试未通过", "项");
        unitMap.put("旅客服务投诉", "件");
        unitMap.put("服务监察", "项");
        unitMap.put("典型服务案例", "次");
        unitMap.put("典型案例查获", "次");
        unitMap.put("考试成绩", "次");

        Long topSiteId = DeptUtils.getTopSiteId(sysDeptService.selectDeptById(SecurityUtils.getDeptId()));
        // 获取所有部门信息
        Map<Long, SysDept> deptMap = getDeptMap();
        // 构建大队到其所有子部门ID的映射
        Map<Long, Set<Long>> brigadeSubDeptsMap = buildBrigadeSubDeptsMap(getDeptMap());

        LedgerWarningDetailVO result = new LedgerWarningDetailVO();
        ScoreIndicator scoreIndicatorQuery = new ScoreIndicator();
        scoreIndicatorQuery.setStatus("0");
        scoreIndicatorQuery.setOrg(ScoreLevelEnum.PERSON.getCode());
        scoreIndicatorQuery.setLevel(2);
        List<ScoreIndicator> scoreIndicatorList = scoreIndicatorService.selectList(scoreIndicatorQuery);
        scoreIndicatorList = scoreIndicatorList.stream().filter(scoreIndicator -> scoreIndicatorNameList.contains(scoreIndicator.getName())).collect(Collectors.toList());
        List<Long> scoreIndicatorIdList = scoreIndicatorList.stream().map(ScoreIndicator::getId).collect(Collectors.toList());
        List<Long> userIdList = new ArrayList<>();
        List<String> userNameList = new ArrayList<>();
        Map<Long, SysUser> sysUserMap = new HashMap<>();
        if (ObjUtil.isNotNull(queryReq.getUserId())) {
            userIdList.add(queryReq.getUserId());
            SysUser sysUser = sysUserService.selectUserById(queryReq.getUserId());
            userNameList.add(sysUser.getNickName());
            sysUserMap.put(queryReq.getUserId(), sysUser);
        } else {
            Long targetDeptId = ObjUtil.isNotNull(queryReq.getGroupId()) ? queryReq.getGroupId()
                    : ObjUtil.isNotNull(queryReq.getTeamId()) ? queryReq.getTeamId()
                    : ObjUtil.isNotNull(queryReq.getDeptId()) ? queryReq.getDeptId()
                    : topSiteId;
            List<SysUser> sysUserList = sysUserService.selectUserByDeptId(targetDeptId);
            userIdList.addAll(sysUserList.stream().map(SysUser::getUserId).collect(Collectors.toList()));
            userNameList.addAll(sysUserList.stream().map(SysUser::getNickName).collect(Collectors.toList()));
            sysUserMap.putAll(sysUserList.stream().collect(Collectors.toMap(SysUser::getUserId, user -> user)));
        }
        Map<String, BigDecimal> overallScoreMap = employeePortraitService.getPortraitTotalScore(userNameList, DateUtil.formatDate(queryReq.getStartDate()), DateUtil.formatDate(queryReq.getEndDate()));
        List<ScoreEvent> scoreEventList = ledgerWarningMapper.selectScoreEventList(queryReq.getStartDate(), queryReq.getEndDate(), scoreIndicatorIdList, userIdList);
//        // 由于person_name存在多用户时person_id为空,因此不能根据person_id进行分组处理数据
//        Map<Long, List<ScoreEvent>> scoreEventMap = scoreEventList.stream().collect(Collectors.groupingBy(ScoreEvent::getPersonId));
        List<LedgerWarningDetailItemVO> ledgerWarningDetailItemList = new ArrayList<>();
        userIdList.forEach(userId -> {
            LedgerWarningDetailItemVO ledgerWarningDetailItem = new LedgerWarningDetailItemVO();
            SysUser sysUser = sysUserMap.get(userId);
            ledgerWarningDetailItem.setUserId(sysUser.getUserId());
            ledgerWarningDetailItem.setUserName(sysUser.getUserName());
            ledgerWarningDetailItem.setNickName(sysUser.getNickName());
            ledgerWarningDetailItem.setDeptId(sysUser.getDeptId());
            SysDept dept = deptMap.get(findUserBrigade(sysUser.getDeptId(), brigadeSubDeptsMap));
            if (ObjUtil.isNotNull(dept)) {
                ledgerWarningDetailItem.setDeptName(dept.getDeptName());
            }
            BigDecimal overallScore = overallScoreMap.get(sysUser.getNickName());
            ledgerWarningDetailItem.setOverallScore(overallScore);
            if (ledgerWarningDetailItem.getOverallScore().compareTo(BigDecimal.valueOf(75)) < 0) {
                ledgerWarningDetailItem.setWarningLevel(LedgerAlertLevelEnum.RED_ALERT.getCode());
                ledgerWarningDetailItem.setStatusLabel(LedgerStatusLabelEnum.EMERGENCY_INTERVENTION.getCode());
            } else if (ledgerWarningDetailItem.getOverallScore().compareTo(BigDecimal.valueOf(90)) >= 0) {
                ledgerWarningDetailItem.setWarningLevel(LedgerAlertLevelEnum.EXCELLENT_BENCHMARK.getCode());
                ledgerWarningDetailItem.setStatusLabel(LedgerStatusLabelEnum.COMMENDATION_AND_MOTIVATION.getCode());
            } else {
                ledgerWarningDetailItem.setWarningLevel(LedgerAlertLevelEnum.NORMAL_RANGE.getCode());
                ledgerWarningDetailItem.setStatusLabel(LedgerStatusLabelEnum.REGULAR_COACHING.getCode());
            }
//            // 由于person_name存在多用户时person_id为空,因此不能根据person_id进行分组处理数据
//            List<ScoreEvent> userScoreEventList = scoreEventMap.get(userId);
            List<ScoreEvent> userScoreEventList = scoreEventList.stream()
                    .filter(scoreEvent -> {
                        if (ObjUtil.isNull(scoreEvent.getDimensionId()) || StrUtil.isEmpty(scoreEvent.getPersonName())) {
                            return false;
                        }
                        boolean matched = false;
                        for (String n : scoreEvent.getPersonName().split("[,，]")) {
                            if (sysUser.getNickName().equals(n.trim())) {
                                matched = true;
                                break;
                            }
                        }
                        return matched;
                    })
                    .collect(Collectors.toList());
            if (CollUtil.isNotEmpty(userScoreEventList)) {
                Map<String, Integer> userScoreEventCountMap = userScoreEventList.stream().collect(Collectors.groupingBy(ScoreEvent::getLevel2Name, Collectors.summingInt(e -> 1)));
                String coreRisksOrOutstandingAchievements = userScoreEventCountMap.entrySet().stream()
                        .map(entry -> entry.getKey() + entry.getValue() + unitMap.get(entry.getKey()))
                        .collect(Collectors.joining(","));
                ledgerWarningDetailItem.setCoreRisksOrOutstandingAchievements(coreRisksOrOutstandingAchievements);
            }
            ledgerWarningDetailItemList.add(ledgerWarningDetailItem);
        });
        List<LedgerWarningDetailItemVO> redAlertList = ledgerWarningDetailItemList.stream().filter(item -> StrUtil.equals(LedgerAlertLevelEnum.RED_ALERT.getCode(), item.getWarningLevel())).collect(Collectors.toList());
        List<LedgerWarningDetailItemVO> excellentBenchmarkList = ledgerWarningDetailItemList.stream().filter(item -> StrUtil.equals(LedgerAlertLevelEnum.EXCELLENT_BENCHMARK.getCode(), item.getWarningLevel())).collect(Collectors.toList());
        result.setRedAlertNum(redAlertList.size());
        result.setExcellentBenchmarkNum(excellentBenchmarkList.size());
        BigDecimal sum = ledgerWarningDetailItemList.stream().map(LedgerWarningDetailItemVO::getOverallScore).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal averageComprehensiveScore = CollUtil.isEmpty(ledgerWarningDetailItemList) ? BigDecimal.ZERO : sum.divide(BigDecimal.valueOf(ledgerWarningDetailItemList.size()), 2, RoundingMode.HALF_UP);
        result.setAverageComprehensiveScore(averageComprehensiveScore);
        result.setLedgerWarningDetailItemList(ledgerWarningDetailItemList);
        return result;
    }

    /**
     * 获取部门映射表
     */
    private Map<Long, SysDept> getDeptMap() {
        List<SysDept> allDepts = sysDeptService.selectDeptInfoAll(new SysDept());
        return allDepts.stream()
                .collect(Collectors.toMap(SysDept::getDeptId, dept -> dept, (v1, v2) -> v1));
    }

    /**
     * 构建大队到其所有子部门ID的映射
     * 用于按大队级别统计，包括大队及其下属所有部门
     *
     * @param deptMap 部门映射表
     * @return 大队ID到其所有子部门ID集合的映射
     */
    private Map<Long, Set<Long>> buildBrigadeSubDeptsMap(Map<Long, SysDept> deptMap) {
        // 获取所有大队部门
        List<SysDept> allBrigades = deptMap.values().stream()
                .filter(dept -> DeptTypeEnum.BRIGADE.getCode().equals(dept.getDeptType()))
                .collect(Collectors.toList());
        // 构建大队到其所有子部门ID的映射
        Map<Long, Set<Long>> brigadeSubDeptsMap = new HashMap<>();
        for (SysDept brigade : allBrigades) {
            Set<Long> subDeptIds = getAllSubDeptIds(brigade.getDeptId(), deptMap);
            brigadeSubDeptsMap.put(brigade.getDeptId(), subDeptIds);
        }
        return brigadeSubDeptsMap;
    }

    /**
     * 获取指定部门及其所有子部门的ID集合
     *
     * @param deptId 部门ID
     * @param deptMap 部门映射表
     * @return 包含当前部门及所有子部门的ID集合
     */
    private Set<Long> getAllSubDeptIds(Long deptId, Map<Long, SysDept> deptMap) {
        Set<Long> result = new HashSet<>();
        // 包含当前部门
        result.add(deptId);
        for (SysDept dept : deptMap.values()) {
            if (dept.getParentId() != null && dept.getParentId().equals(deptId)) {
                // 递归获取子部门的子部门
                result.addAll(getAllSubDeptIds(dept.getDeptId(), deptMap));
            }
        }
        return result;
    }

    /**
     * 查找用户所属的大队ID
     *
     * @param userDeptId 用户所在部门ID
     * @param brigadeSubDeptsMap 大队到其所有子部门ID的映射
     * @return 所属大队ID，如果未找到则返回null
     */
    private Long findUserBrigade(Long userDeptId, Map<Long, Set<Long>> brigadeSubDeptsMap) {
        for (Map.Entry<Long, Set<Long>> entry : brigadeSubDeptsMap.entrySet()) {
            if (entry.getValue().contains(userDeptId)) {
                return entry.getKey();
            }
        }
        return null;
    }

}
