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

import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.ledger.domain.ScoreDimension;
import com.sundot.airport.ledger.domain.ScoreEvent;
import com.sundot.airport.ledger.domain.vo.MemberScoreVO;
import com.sundot.airport.ledger.mapper.ScoreDimensionMapper;
import com.sundot.airport.ledger.mapper.ScoreEventMapper;
import com.sundot.airport.ledger.service.IScoreRadarService;
import com.sundot.airport.system.mapper.SysDeptMapper;
import com.sundot.airport.system.mapper.SysUserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ScoreRadarServiceImpl implements IScoreRadarService {

    @Autowired
    private ScoreEventMapper scoreEventMapper;

    @Autowired
    private ScoreDimensionMapper scoreDimensionMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public List<String> selectTeamList() {
        SysDept query = new SysDept();
        query.setDeptType("TEAMS");
        return sysDeptMapper.selectDeptList(query).stream()
                .map(SysDept::getDeptName)
                .filter(name -> name != null && !name.isEmpty())
                .sorted()
                .collect(Collectors.toList());
    }

    @Override
    public List<MemberScoreVO> selectMemberScores(String teamName) {
        // 1. 获取所有启用维度（按 sortOrder）
        ScoreDimension dq = new ScoreDimension();
        dq.setStatus("0");
        List<ScoreDimension> dimensions = scoreDimensionMapper.selectList(dq);
        dimensions.sort(Comparator.comparing(d -> (d.getSortOrder() == null ? 999 : d.getSortOrder())));

        // 2. 从 sys_dept + sys_user 获取小组完整成员列表
        //    即使没有加减分记录，成员也需要展示
        Set<String> rosterNames = getMemberRoster(teamName);

        // 3. 加载全量事件记录，按花名册姓名过滤
        //    不依赖 team_name 字段（台账导入的 team_name 是班组级别，与小组名不匹配）
        //    通过姓名匹配花名册，确保只统计本小组成员的事件
        //    原始数据不规范：person_name 可能为 "张三,李四,王五"，需拆分后各自计分
        List<ScoreEvent> events = scoreEventMapper.selectList(new ScoreEvent());

        // 4. 按拆分后的姓名分组汇总各维度得分（仅统计花名册成员）
        //    Map<personName, Map<dimensionId, eventScoreSum>>
        Map<String, Map<Long, BigDecimal>> personDimMap = new LinkedHashMap<>();
        for (ScoreEvent e : events) {
            String rawName = e.getPersonName();
            if (rawName == null || rawName.trim().isEmpty()) continue;
            Long dimId = e.getDimensionId();
            if (dimId == null) continue;
            BigDecimal val = e.getTotalScore() != null ? e.getTotalScore() : BigDecimal.ZERO;

            // 拆分逗号分隔的多人姓名，只处理在本小组花名册中的人
            String[] names = rawName.split("[,，]");
            for (String n : names) {
                String name = n.trim();
                if (name.isEmpty()) continue;
                if (!rosterNames.contains(name)) continue; // 不在本组，跳过
                personDimMap
                        .computeIfAbsent(name, k -> new HashMap<>())
                        .merge(dimId, val, BigDecimal::add);
            }
        }

        // 5. 合并花名册与事件记录：花名册中的人若无事件记录，也需要出现
        //    先把花名册成员加入（保证顺序：花名册在前，事件中有但花名册没有的追加到后面）
        Set<String> allNames = new LinkedHashSet<>(rosterNames);
        allNames.addAll(personDimMap.keySet());

        // 6. 构建 VO
        List<MemberScoreVO> result = new ArrayList<>();
        for (String name : allNames) {
            Map<Long, BigDecimal> dimScoreMap = personDimMap.getOrDefault(name, Collections.emptyMap());

            MemberScoreVO vo = new MemberScoreVO();
            vo.setPersonName(name);
            vo.setTeamName(teamName);

            List<MemberScoreVO.DimScore> dimScores = new ArrayList<>();
            BigDecimal totalScore = BigDecimal.ZERO;

            for (ScoreDimension dim : dimensions) {
                BigDecimal eventScore = dimScoreMap.getOrDefault(dim.getId(), BigDecimal.ZERO);
                BigDecimal base = dim.getBaseScore() != null ? dim.getBaseScore() : BigDecimal.valueOf(80);
                BigDecimal dimScore = base.add(eventScore);

                // 加权贡献 = dimScore × weight / 100
                BigDecimal weight = dim.getWeight() != null ? dim.getWeight() : BigDecimal.ZERO;
                BigDecimal contribution = dimScore.multiply(weight)
                        .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);

                MemberScoreVO.DimScore ds = new MemberScoreVO.DimScore();
                ds.setDimensionId(dim.getId());
                ds.setDimensionName(dim.getName());
                ds.setWeight(weight);
                ds.setBaseScore(base);
                ds.setEventScore(eventScore);
                ds.setScore(dimScore);
                ds.setContribution(contribution);
                dimScores.add(ds);

                totalScore = totalScore.add(contribution);
            }

            vo.setDimensions(dimScores);
            vo.setTotalScore(totalScore.setScale(1, RoundingMode.HALF_UP));
            result.add(vo);
        }

        // 7. 按综合得分降序排序
        result.sort((a, b) -> b.getTotalScore().compareTo(a.getTotalScore()));
        return result;
    }

    /**
     * 从 sys_dept + sys_user 查询班组完整花名册
     * dept_type='MANAGER' 对应班组，nick_name 对应 person_name
     */
    private Set<String> getMemberRoster(String teamName) {
        // 找班组对应的 dept_id
        SysDept deptQuery = new SysDept();
        deptQuery.setDeptType("TEAMS");
        deptQuery.setDeptName(teamName);
        List<SysDept> depts = sysDeptMapper.selectDeptList(deptQuery);
        if (depts == null || depts.isEmpty()) {
            return new LinkedHashSet<>();
        }
        Long deptId = depts.get(0).getDeptId();

        // 查该班组下所有在职用户的 nick_name
        List<SysUser> users = sysUserMapper.selectUsersByDeptId(deptId);
        if (users == null) {
            return new LinkedHashSet<>();
        }
        return users.stream()
                .filter(u -> "0".equals(u.getStatus()) && "0".equals(u.getDelFlag()))
                .map(SysUser::getNickName)
                .filter(n -> n != null && !n.trim().isEmpty())
                .collect(Collectors.toCollection(LinkedHashSet::new));
    }
}
