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

import com.sundot.airport.common.core.domain.entity.SysRole;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.enums.DeptTypeEnum;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.ledger.domain.ScoreDimension;
import com.sundot.airport.ledger.domain.ScoreEvent;
import com.sundot.airport.ledger.dto.DeptMemberDistributionDTO;
import com.sundot.airport.ledger.dto.DeptMemberDTO;
import com.sundot.airport.ledger.dto.DeptPortraitQueryDTO;
import com.sundot.airport.ledger.dto.StationTeamStatsDTO;
import com.sundot.airport.ledger.mapper.ScoreDimensionMapper;
import com.sundot.airport.ledger.mapper.ScoreEventMapper;
import com.sundot.airport.ledger.dto.GroupPortraitDTO;
import com.sundot.airport.ledger.service.IDeptPortraitService;
import com.sundot.airport.ledger.service.IGroupPortraitService;
import com.sundot.airport.system.domain.BasePosition;
import com.sundot.airport.system.domain.SysPost;
import com.sundot.airport.system.domain.SysUserPost;
import com.sundot.airport.system.mapper.BasePositionMapper;
import com.sundot.airport.system.mapper.SysDeptMapper;
import com.sundot.airport.system.mapper.SysPostMapper;
import com.sundot.airport.system.mapper.SysRoleMapper;
import com.sundot.airport.system.mapper.SysUserMapper;
import com.sundot.airport.system.mapper.SysUserPostMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <b>功能名：</b>DeptPortraitServiceImpl<br>
 * <b>说明：</b> 部门画像Service实现（团队成员查询）<br>
 * <b>著作权：</b> Copyright (C) 2025 SUNDOT CORPORATION<br>
 *
 * @author Claude
 */
@Service
public class DeptPortraitServiceImpl implements IDeptPortraitService {

    private static final Logger log = LoggerFactory.getLogger(DeptPortraitServiceImpl.class);

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ScoreEventMapper scoreEventMapper;

    @Autowired
    private ScoreDimensionMapper scoreDimensionMapper;

    @Autowired
    private BasePositionMapper basePositionMapper;

    @Autowired
    private SysPostMapper sysPostMapper;

    @Autowired
    private SysUserPostMapper sysUserPostMapper;

    @Autowired
    private IGroupPortraitService groupPortraitService;

    @Override
    public List<DeptMemberDTO> getDeptMembers(DeptPortraitQueryDTO query) {
        // 递归查询所有下级部门的用户
        SysUser userQuery = new SysUser();
        userQuery.setDeptId(query.getDeptId());
        userQuery.setStatus("0");
        
        List<SysUser> allUsers = sysUserMapper.selectUserList(userQuery);
        
        if (allUsers == null || allUsers.isEmpty()) {
            return Collections.emptyList();
        }

        List<DeptMemberDTO> result = allUsers.stream()
                .map(user -> convertToDeptMemberDTO(user, query.getStartDate(), query.getEndDate()))
                .collect(Collectors.toList());

        return result;
    }

    @Override
    public DeptMemberDistributionDTO getMemberDistribution(DeptPortraitQueryDTO query) {
        SysUser userQuery = new SysUser();
        userQuery.setDeptId(query.getDeptId());
        userQuery.setStatus("0");
        
        List<SysUser> allUsers = sysUserMapper.selectUserList(userQuery);
        
        if (allUsers == null || allUsers.isEmpty()) {
            return new DeptMemberDistributionDTO();
        }

        DeptMemberDistributionDTO distribution = new DeptMemberDistributionDTO();
        distribution.setSexDistribution(calculateDistribution(allUsers, SysUser::getSex, this::decodeSex));
        distribution.setNationDistribution(calculateDistribution(allUsers, SysUser::getNation, this::decodeNation));
        distribution.setPoliticalDistribution(calculateDistribution(allUsers, SysUser::getPoliticalStatus, this::decodePoliticalStatusForDistribution));
        
        return distribution;
    }

    @Override
    public DeptMemberDistributionDTO getPositionDistribution(DeptPortraitQueryDTO query) {
        SysUser userQuery = new SysUser();
        userQuery.setDeptId(query.getDeptId());
        userQuery.setStatus("0");
        
        List<SysUser> allUsers = sysUserMapper.selectUserList(userQuery);
        
        if (allUsers == null || allUsers.isEmpty()) {
            return new DeptMemberDistributionDTO();
        }

        DeptMemberDistributionDTO distribution = new DeptMemberDistributionDTO();
        
        // 统计职业资格等级分布
        distribution.setQualificationDistribution(calculateQualificationDistribution(allUsers));
        
        // 统计开机年限分布
        distribution.setXrayYearDistribution(calculateXrayYearDistribution(allUsers));
        
        // 统计岗位资质分布
        distribution.setPositionDistribution(calculatePositionDistribution(allUsers));
        
        return distribution;
    }

    /**
     * 统计职业资格等级分布
     */
    private List<DeptMemberDistributionDTO.DistributionItem> calculateQualificationDistribution(List<SysUser> users) {
        return users.stream()
                .map(SysUser::getQualificationLevel)
                .filter(Objects::nonNull)
                .filter(s -> !s.isEmpty())
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .entrySet().stream()
                .map(entry -> new DeptMemberDistributionDTO.DistributionItem(
                        decodeQualificationLevelForChart(entry.getKey()),
                        entry.getValue().intValue()
                ))
                .sorted((a, b) -> {
                    // 按等级排序
                    String[] order = {"等级1", "等级2", "等级3", "等级4", "等级5"};
                    return Arrays.asList(order).indexOf(a.getName()) - Arrays.asList(order).indexOf(b.getName());
                })
                .collect(Collectors.toList());
    }

    /**
     * 统计开机年限分布
     */
    private List<DeptMemberDistributionDTO.DistributionItem> calculateXrayYearDistribution(List<SysUser> users) {
        Map<String, Integer> yearRanges = new LinkedHashMap<>();
        yearRanges.put("0-3", 0);
        yearRanges.put("4-7", 0);
        yearRanges.put("8-11", 0);
        yearRanges.put("12-15", 0);
        yearRanges.put("15-18", 0);

        for (SysUser user : users) {
            if (user.getXrayOperatorStarttime() != null) {
                int years = calculateYears(user.getXrayOperatorStarttime());
                if (years >= 0 && years <= 3) {
                    yearRanges.put("0-3", yearRanges.get("0-3") + 1);
                } else if (years >= 4 && years <= 7) {
                    yearRanges.put("4-7", yearRanges.get("4-7") + 1);
                } else if (years >= 8 && years <= 11) {
                    yearRanges.put("8-11", yearRanges.get("8-11") + 1);
                } else if (years >= 12 && years <= 15) {
                    yearRanges.put("12-15", yearRanges.get("12-15") + 1);
                } else if (years >= 16) {
                    yearRanges.put("15-18", yearRanges.get("15-18") + 1);
                }
            }
        }

        return yearRanges.entrySet().stream()
                .map(entry -> new DeptMemberDistributionDTO.DistributionItem(
                        entry.getKey() + "年",
                        entry.getValue()
                ))
                .collect(Collectors.toList());
    }

    /**
     * 统计岗位资质分布
     * 正确逻辑：通过用户ID查询sys_user_post找到岗位ID，再查询sys_post获取岗位信息
     * 使用批量查询优化性能
     */
    private List<DeptMemberDistributionDTO.DistributionItem> calculatePositionDistribution(List<SysUser> users) {
        if (users == null || users.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 1. 收集所有用户ID
        List<Long> userIds = users.stream()
                .map(SysUser::getUserId)
                .collect(Collectors.toList());
        
        // 2. 批量查询用户岗位关系
        List<SysUserPost> userPostRelations = sysUserPostMapper.selectUserPostByUserIds(userIds);
        
        if (userPostRelations == null || userPostRelations.isEmpty()) {
            return Collections.emptyList();
        }
        
        // 3. 收集所有岗位ID
        List<Long> postIds = userPostRelations.stream()
                .map(SysUserPost::getPostId)
                .distinct()
                .collect(Collectors.toList());
        
        // 4. 批量查询岗位信息
        Map<Long, String> postIdToNameMap = new HashMap<>();
        if (!postIds.isEmpty()) {
            List<SysPost> posts = sysPostMapper.selectPostsByIds(postIds);
            for (SysPost post : posts) {
                if (post != null && post.getPostName() != null) {
                    postIdToNameMap.put(post.getPostId(), post.getPostName());
                }
            }
        }
        
        // 5. 统计每个岗位的人数
        Map<String, Integer> positionMap = new LinkedHashMap<>();
        for (SysUserPost relation : userPostRelations) {
            String postName = postIdToNameMap.get(relation.getPostId());
            if (postName != null && !postName.isEmpty()) {
                positionMap.merge(postName, 1, Integer::sum);
            }
        }
        
        return positionMap.entrySet().stream()
                .map(entry -> new DeptMemberDistributionDTO.DistributionItem(
                        entry.getKey(),
                        entry.getValue()
                ))
                .collect(Collectors.toList());
    }

    /**
     * 解码职业资格等级（用于图表显示）
     */
    private String decodeQualificationLevelForChart(String v) {
        if (v == null) return "未知";
        switch (v) {
            case "LEVEL_ONE": return "等级1";
            case "LEVEL_TWO": return "等级2";
            case "LEVEL_THREE": return "等级3";
            case "LEVEL_FOUR": return "等级4";
            case "LEVEL_FIVE": return "等级5";
            default: return v;
        }
    }

    private List<DeptMemberDistributionDTO.DistributionItem> calculateDistribution(
            List<SysUser> users,
            Function<SysUser, String> extractor,
            Function<String, String> decoder) {
        
        return users.stream()
                .map(extractor)
                .filter(Objects::nonNull)
                .filter(s -> !s.isEmpty())
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .entrySet().stream()
                .map(entry -> new DeptMemberDistributionDTO.DistributionItem(
                        decoder.apply(entry.getKey()),
                        entry.getValue().intValue()
                ))
                .sorted((a, b) -> b.getCount() - a.getCount())
                .collect(Collectors.toList());
    }

    private String decodeSex(String sex) {
        if (sex == null || sex.isEmpty()) return "未知";
        return "0".equals(sex) ? "男" : "1".equals(sex) ? "女" : "其他";
    }

    private String decodeNation(String nation) {
        if (nation == null || nation.isEmpty()) return "未知";
        return nation;
    }

    private String decodePoliticalStatusForDistribution(String politicalStatus) {
        if (politicalStatus == null || politicalStatus.isEmpty()) return "未知";
        switch (politicalStatus) {
            case "COMMUNIST_PARTY_MEMBER": return "中共党员";
            case "PROBATIONARY_COMMUNIST_PARTY_MEMBER": return "中共预备党员";
            case "COMMUNIST_YOUTH_LEAGUE_MEMBER": return "共青团员";
            case "MASS_PUBLIC": return "群众";
            default: return politicalStatus;
        }
    }

    private DeptMemberDTO convertToDeptMemberDTO(SysUser user, String startDate, String endDate) {
        DeptMemberDTO dto = new DeptMemberDTO();
        dto.setUserId(user.getUserId());
        dto.setPersonName(user.getNickName());
        dto.setSex("0".equals(user.getSex()) ? "男" : "1".equals(user.getSex()) ? "女" : "");
        dto.setNation(user.getNation());
        dto.setPoliticalStatus(decodePoliticalStatus(user.getPoliticalStatus()));
        dto.setQualificationLevel(decodeQualificationLevel(user.getQualificationLevel()));
        dto.setAge(calculateAgeFromIdCard(user.getCardNumber()));
        
        if (user.getEntryDate() != null) {
            Integer workYears = calculateYears(user.getEntryDate());
            dto.setWorkYears(workYears);
        }
        if (user.getXrayOperatorStarttime() != null) {
            dto.setXrayOperatorYears(calculateYears(user.getXrayOperatorStarttime()));
        }
        
        List<SysRole> roles = sysRoleMapper.selectRolesByUserName(user.getUserName());
        if (roles != null && !roles.isEmpty()) {
            String roleNames = roles.stream()
                    .map(SysRole::getRoleName)
                    .filter(s -> s != null && !s.isEmpty())
                    .collect(Collectors.joining("、"));
            dto.setRoleNames(roleNames);
        }
        
        BigDecimal totalScore = calculateTotalScore(user.getNickName(), startDate, endDate);
        dto.setTotalScore(totalScore);

        return dto;
    }

    private BigDecimal calculateTotalScore(String personName, String beginTime, String endTime) {
        ScoreEvent eventQuery = new ScoreEvent();
        eventQuery.setPersonName(personName);
        if (beginTime != null && !beginTime.isEmpty()) {
            eventQuery.getParams().put("beginTime", beginTime);
        }
        if (endTime != null && !endTime.isEmpty()) {
            eventQuery.getParams().put("endTime", endTime);
        }
        List<ScoreEvent> events = scoreEventMapper.selectList(eventQuery);

        if (events == null || events.isEmpty()) {
            return BigDecimal.valueOf(80);
        }

        Map<Long, BigDecimal> dimMap = new HashMap<>();
        for (ScoreEvent e : events) {
            Long dimId = e.getDimensionId();
            if (dimId == null) continue;
            String raw = e.getPersonName();
            if (raw == null) continue;
            boolean matched = false;
            for (String n : raw.split("[,，]")) {
                if (personName.equals(n.trim())) {
                    matched = true;
                    break;
                }
            }
            if (!matched) continue;
            BigDecimal val = e.getTotalScore() != null ? e.getTotalScore() : BigDecimal.ZERO;
            dimMap.merge(dimId, val, BigDecimal::add);
        }

        ScoreDimension dq = new ScoreDimension();
        dq.setStatus("0");
        List<ScoreDimension> dims = scoreDimensionMapper.selectList(dq);
        dims.sort(Comparator.comparing(d -> d.getSortOrder() == null ? 999 : d.getSortOrder()));

        BigDecimal total = BigDecimal.ZERO;
        for (ScoreDimension dim : dims) {
            BigDecimal eventScore = dimMap.getOrDefault(dim.getId(), BigDecimal.ZERO);
            BigDecimal base = dim.getBaseScore() != null ? dim.getBaseScore() : BigDecimal.valueOf(80);
            BigDecimal dimScore = base.add(eventScore);
            BigDecimal weight = dim.getWeight() != null ? dim.getWeight() : BigDecimal.ZERO;
            BigDecimal contribution = dimScore.multiply(weight)
                    .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
            total = total.add(contribution);
        }

        return total.setScale(1, RoundingMode.HALF_UP);
    }

    @Override
    public List<StationTeamStatsDTO> getStationTeamStats(DeptPortraitQueryDTO query) {
        // 1. 验证是站级别
        SysDept station = sysDeptMapper.selectDeptById(query.getDeptId());
        if (station == null) {
            throw new RuntimeException("请选择站级别部门");
        }

        // 2. 查询站下所有部门(BRIGADE)
        SysDept deptQuery = new SysDept();
        deptQuery.setParentId(query.getDeptId());
        deptQuery.setDeptType(getChildDeptType(station.getDeptType()));
        deptQuery.setStatus("0");
        List<SysDept> brigades = sysDeptMapper.selectDeptList(deptQuery);

        if (brigades == null || brigades.isEmpty()) {
            return Collections.emptyList();
        }

        // 3. 为每个部门计算统计信息
        List<StationTeamStatsDTO> result = new ArrayList<>();
        for (SysDept brigade : brigades) {
            StationTeamStatsDTO stats = calculateDeptStats(brigade, query.getStartDate(), query.getEndDate());
            if (stats != null) {
                result.add(stats);
            }
        }

        return result;
    }

    private String getChildDeptType(String deptType) {
        if (deptType == null || deptType.isEmpty()) {
            return null;
        }

        switch (deptType) {
            case "STATION":
                return DeptTypeEnum.BRIGADE.getCode();
            case "BRIGADE":
                return DeptTypeEnum.MANAGER.getCode();
            case "MANAGER":
                return DeptTypeEnum.TEAMS.getCode();
            default:
                return null;
        }
    }

    @Override
    public StationTeamStatsDTO getTeamStats(DeptPortraitQueryDTO query) {
        SysDept sysDept = sysDeptMapper.selectDeptById(query.getDeptId());
        if (sysDept == null) {
            throw new ServiceException("部门不存在");
        }
        return calculateDeptStats(sysDept, query.getStartDate(), query.getEndDate());
    }

    /**
     * 计算单个部门的团队画像统计信息
     */
    private StationTeamStatsDTO calculateDeptStats(SysDept dept, String startDate, String endDate) {
        // 查询部门所有成员
        SysUser userQuery = new SysUser();
        userQuery.setDeptId(dept.getDeptId());
        userQuery.setStatus("0");
        List<SysUser> members = sysUserMapper.selectUserList(userQuery);

        if (members == null || members.isEmpty()) {
            return null;
        }

        StationTeamStatsDTO stats = new StationTeamStatsDTO();
        stats.setDeptId(dept.getDeptId());
        stats.setDeptName(dept.getDeptName());
        stats.setEmployeeCount(members.size());

        // 计算各项统计
        int partyCount = 0;
        int totalAge = 0;
        int totalWorkYears = 0;
        int totalXrayOperatorYears = 0;
        int validAgeCount = 0;
        int validWorkYearsCount = 0;
        int validXrayOperatorYearsCount = 0;
        Map<String, Integer> qualLevelCount = new HashMap<>();
        
        for (SysUser user : members) {
            // 党员数量(中共党员 + 中共预备党员)
            String politicalStatus = decodePoliticalStatus(user.getPoliticalStatus());
            if ("中共党员".equals(politicalStatus) || "中共预备党员".equals(politicalStatus)) {
                partyCount++;
            }
        
            // 年龄
            Integer age = calculateAgeFromIdCard(user.getCardNumber());
            if (age != null && age > 0) {
                totalAge += age;
                validAgeCount++;
            }
        
            // 工龄(从入职时间计算)
            if (user.getEntryDate() != null) {
                Integer workYears = calculateYears(user.getEntryDate());
                if (workYears != null) {
                    totalWorkYears += workYears;
                    validWorkYearsCount++;
                }
            }
        
            // 开机年限(从开机时间计算)
            if (user.getXrayOperatorStarttime() != null) {
                Integer xrayYears = calculateYears(user.getXrayOperatorStarttime());
                if (xrayYears != null) {
                    totalXrayOperatorYears += xrayYears;
                    validXrayOperatorYearsCount++;
                }
            }
        
            // 职业资格等级
            if (user.getQualificationLevel() != null && !user.getQualificationLevel().isEmpty()) {
                String level = decodeQualificationLevel(user.getQualificationLevel());
                qualLevelCount.merge(level, 1, Integer::sum);
            }
        }

        stats.setPartyMemberCount(partyCount);
        stats.setAvgAge(validAgeCount > 0 ? Math.round((double) totalAge / validAgeCount * 10) / 10.0 : 0);
        stats.setAvgWorkYears(validWorkYearsCount > 0 ? Math.round((double) totalWorkYears / validWorkYearsCount * 10) / 10.0 : 0);
        stats.setAvgXrayOperatorYears(validXrayOperatorYearsCount > 0 ? Math.round((double) totalXrayOperatorYears / validXrayOperatorYearsCount * 10) / 10.0 : 0);

        // 职业资格证书等级（总个数）
        int totalQualificationCount = qualLevelCount.values().stream()
                .mapToInt(Integer::intValue)
                .sum();
        stats.setQualificationLevel(String.valueOf(totalQualificationCount));

        // 计算综合得分（使用维度得分一览的总分逻辑）
        try {
            DeptPortraitQueryDTO portraitQuery = new DeptPortraitQueryDTO();
            portraitQuery.setDeptId(dept.getDeptId());
            portraitQuery.setStartDate(startDate);
            portraitQuery.setEndDate(endDate);
            GroupPortraitDTO portrait = groupPortraitService.getGroupPortrait(portraitQuery);
            stats.setTotalScore(portrait.getTotalScore() != null ? portrait.getTotalScore() : BigDecimal.ZERO);
        } catch (Exception e) {
            log.warn("计算部门[{}]综合得分失败: {}", dept.getDeptName(), e.getMessage());
            stats.setTotalScore(BigDecimal.ZERO);
        }

        return stats;
    }

    private Integer calculateAgeFromIdCard(String idCard) {
        if (idCard == null || idCard.length() < 14) {
            return null;
        }
        try {
            String birthDateStr = idCard.substring(6, 14);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            LocalDate birthDate = LocalDate.parse(birthDateStr, formatter);
            LocalDate now = LocalDate.now();
            return Period.between(birthDate, now).getYears();
        } catch (Exception e) {
            log.warn("从身份证计算年龄失败: {}", idCard, e);
            return null;
        }
    }

    private Integer calculateYears(Date startDate) {
        if (startDate == null) {
            return null;
        }
        long nowMs = System.currentTimeMillis();
        return (int) ((nowMs - startDate.getTime()) / (365L * 24 * 3600 * 1000));
    }

    private String decodePoliticalStatus(String v) {
        if (v == null) return "";
        switch (v) {
            case "COMMUNIST_PARTY_MEMBER": return "中共党员";
            case "PROBATIONARY_COMMUNIST_PARTY_MEMBER": return "中共预备党员";
            case "COMMUNIST_YOUTH_LEAGUE_MEMBER": return "共青团员";
            case "MASS_PUBLIC": return "群众";
            default: return v;
        }
    }

    private String decodeQualificationLevel(String v) {
        if (v == null) return "";
        switch (v) {
            case "LEVEL_ONE": return "一级";
            case "LEVEL_TWO": return "二级";
            case "LEVEL_THREE": return "三级";
            case "LEVEL_FOUR": return "四级";
            case "LEVEL_FIVE": return "五级";
            default: return v;
        }
    }
}