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.common.enums.ScoreLevelEnum;
import com.sundot.airport.ledger.domain.LedgerExamScore;
import com.sundot.airport.ledger.domain.ScoreDimension;
import com.sundot.airport.ledger.domain.ScoreEvent;
import com.sundot.airport.ledger.domain.vo.EmployeePortraitVO;
import com.sundot.airport.ledger.mapper.LedgerExamScoreMapper;
import com.sundot.airport.ledger.mapper.LedgerPatrolInspectionMapper;
import com.sundot.airport.ledger.mapper.LedgerSeizureStatsMapper;
import com.sundot.airport.ledger.mapper.ScoreDimensionMapper;
import com.sundot.airport.ledger.mapper.ScoreEventMapper;
import com.sundot.airport.ledger.service.IEmployeePortraitService;
import com.sundot.airport.system.domain.SysPost;
import com.sundot.airport.common.core.domain.entity.SysRole;
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 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 EmployeePortraitServiceImpl implements IEmployeePortraitService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysPostMapper sysPostMapper;

    @Autowired
    private ScoreEventMapper scoreEventMapper;

    @Autowired
    private ScoreDimensionMapper scoreDimensionMapper;

    @Autowired
    private LedgerExamScoreMapper ledgerExamScoreMapper;

    @Autowired
    private LedgerSeizureStatsMapper ledgerSeizureStatsMapper;

    @Autowired
    private LedgerPatrolInspectionMapper ledgerPatrolInspectionMapper;

    private static final Long DIMENSION_ID_EMPLOYEE_STANDARDIZATION = 1L;


    // ── 搜索员工 ─────────────────────────────────────────────────────────────

    @Override
    public List<Map<String, Object>> searchUsers(String keyword) {
        SysUser query = new SysUser();
        query.setNickName(keyword);
        List<SysUser> users = sysUserMapper.selectUserList(query);
        if (users == null) return Collections.emptyList();
        return users.stream()
                .filter(u -> "0".equals(u.getStatus()) && "0".equals(u.getDelFlag()))
                .limit(20)
                .map(u -> {
                    Map<String, Object> m = new LinkedHashMap<>();
                    m.put("userId", u.getUserId());
                    m.put("nickName", u.getNickName());
                    m.put("deptName", u.getDept() != null ? u.getDept().getDeptName() : "");
                    return m;
                })
                .collect(Collectors.toList());
    }

    // ── 获取员工完整画像 ──────────────────────────────────────────────────────

    @Override
    public EmployeePortraitVO getPortrait(String personName, String beginTime, String endTime) {
        EmployeePortraitVO vo = new EmployeePortraitVO();
        vo.setPersonName(personName);

        // 1. 用户基本信息
        fillUserInfo(vo, personName);

        // 2. 六维度评分（从 score_event 聚合）
        fillScores(vo, personName, beginTime, endTime);

        // 3. 最新考试成绩
        fillExamScore(vo, personName);

        // 4. 获奖记录
        fillAwards(vo, personName);

        // 5. 配分明细（全量加减分）
        fillScoreDetails(vo, personName, beginTime, endTime);

        // 6. 质控情况
        fillQualityControl(vo, personName, beginTime, endTime);



        return vo;
    }

    /**
     * 质控情况
     * @param vo 输出对象
     * @param personName 员工姓名
     * @param beginTime 查询开始时间
     * @param endTime 查询结束时间
     */
    private void fillQualityControl(EmployeePortraitVO vo, String personName, String beginTime, String endTime) {
        // 查获违规品次数
        int qcCount = ledgerSeizureStatsMapper.countByInspectorAndDateRange(personName, beginTime, endTime);
        vo.setQualityControlCount(qcCount);

        // 监察问题记录次数
        int standardizationCount = getScoreEventCount(personName, beginTime, endTime, "员工规范化操作");
        vo.setQualityControlEventCount(standardizationCount);

        // 实时质控拦截次数
        int interceptionCount = getScoreEventCount(personName, beginTime, endTime, "后台实时质控拦截");
        vo.setRealtimeInterceptionCount(interceptionCount);

        // 三级质控巡查次数
        int patrolCount = ledgerPatrolInspectionMapper.countByInspectedNameAndDateRange(personName, beginTime, endTime);
        vo.setLevel3QualityControlCount(patrolCount);
    }

    /**
     * 获取特定维度下的质控事件数量
     *
     * @param personName 人员姓名
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @param level2Name 二级维度名称
     * @return 事件数量
     */
    private int getScoreEventCount(String personName, String beginTime, String endTime, String level2Name) {
        ScoreEvent event = buildScoreEvent(personName, beginTime, endTime);
        event.setDimensionId(DIMENSION_ID_EMPLOYEE_STANDARDIZATION);
        event.setLevel2Name(level2Name);
        List<ScoreEvent> events = scoreEventMapper.selectList(event);
        return events == null ? 0 : events.size();
    }

    /**
     * 构建基础的 ScoreEvent 查询对象
     */
    private ScoreEvent buildScoreEvent(String personName, String beginTime, String endTime) {
        ScoreEvent event = new ScoreEvent();
        event.setPersonName(personName);
        // 确保 params 已初始化
        if (event.getParams() == null) {
            event.setParams(new java.util.HashMap<>());
        }
        if (beginTime != null && !beginTime.isEmpty()) {
            event.getParams().put("beginTime", beginTime);
        }
        if (endTime != null && !endTime.isEmpty()) {
            event.getParams().put("endTime", endTime);
        }
        return event;
    }


    // ── 用户基本信息 ─────────────────────────────────────────────────────────

    private void fillUserInfo(EmployeePortraitVO vo, String personName) {
        SysUser query = new SysUser();
        query.setNickName(personName);
        List<SysUser> users = sysUserMapper.selectUserList(query);
        if (users == null || users.isEmpty()) return;

        SysUser user = users.stream()
                .filter(u -> personName.equals(u.getNickName()))
                .findFirst()
                .orElse(users.get(0));

        vo.setUserId(user.getUserId());
        vo.setAvatar(user.getAvatar());
        vo.setPhonenumber(user.getPhonenumber());
        vo.setSex(user.getSex());
        vo.setSexText("0".equals(user.getSex()) ? "男" : "1".equals(user.getSex()) ? "女" : "");
        vo.setSchooling(user.getSchooling());
        vo.setMajor(user.getProfessional());
        vo.setNativePlace(user.getNativePlace());
        vo.setNation(user.getNation());
        vo.setQualificationLevelText(decodeQualLevel(user.getQualificationLevel()));
        vo.setPoliticalStatusText(decodePolitical(user.getPoliticalStatus()));
        vo.setCharacterCharacteristics(decodeChar(user.getCharacterCharacteristics()));
        vo.setWorkingStyle(decodeWorkStyle(user.getWorkingStyle()));
        vo.setStartWorkingDate(user.getStartWorkingDate());
        vo.setSecurityCheckStartDate(user.getSecurityCheckStartDate());
        vo.setEntryDate(user.getEntryDate());
        vo.setXrayOperatorStarttime(user.getXrayOperatorStarttime());
        vo.setSecurityInspectionPosition(user.getSecurityInspectionPosition());

        // 司龄、工龄、开机年限
        long nowMs = System.currentTimeMillis();
        if (user.getStartWorkingDate() != null) {
            vo.setWorkYears((int) ((nowMs - user.getStartWorkingDate().getTime()) / (365L * 24 * 3600 * 1000)));
        }
        if (user.getSecurityCheckStartDate() != null) {
            vo.setSecurityCheckYears((int) ((nowMs - user.getSecurityCheckStartDate().getTime()) / (365L * 24 * 3600 * 1000)));
        }
        if (user.getEntryDate() != null) {
            vo.setCompanyYears((int) ((nowMs - user.getEntryDate().getTime()) / (365L * 24 * 3600 * 1000)));
        }
        if (user.getXrayOperatorStarttime() != null) {
            vo.setXrayOperatorYears((int) ((nowMs - user.getXrayOperatorStarttime().getTime()) / (365L * 24 * 3600 * 1000)));
        }

        // 出生日期（从18位身份证第7~14位提取）
        String card = user.getCardNumber();
        if (card != null && card.length() >= 14) {
            String bd = card.substring(6, 14);
            vo.setBirthday(bd.substring(0, 4) + "-" + bd.substring(4, 6) + "-" + bd.substring(6, 8));
        }

        // 职务（sys_role）
        List<SysRole> roles = sysRoleMapper.selectRolesByUserName(user.getUserName());
        if (roles != null && !roles.isEmpty()) {
            String rn = roles.stream()
                    .map(SysRole::getRoleName)
                    .filter(s -> s != null && !s.isEmpty())
                    .collect(Collectors.joining("、"));
            vo.setRoleNames(rn);
        }

        // 岗位（sys_post）
        List<SysPost> posts = sysPostMapper.selectPostsByUserName(user.getUserName());
        if (posts != null && !posts.isEmpty()) {
            String pn = posts.stream()
                    .map(SysPost::getPostName)
                    .filter(s -> s != null && !s.isEmpty())
                    .collect(Collectors.joining("、"));
            vo.setPostNames(pn);
        }

        // 部门路径
        if (user.getDept() != null) {
            String deptName = user.getDept().getDeptName();
            String parentDeptName = "";
            Long parentId = user.getDept().getParentId();
            if (parentId != null && parentId > 0) {
                SysDept parent = sysDeptMapper.selectDeptById(parentId);
                if (parent != null) parentDeptName = parent.getDeptName();
            }
            vo.setDeptName(deptName);
            vo.setParentDeptName(parentDeptName);
            vo.setDeptPath(parentDeptName.isEmpty() ? deptName : parentDeptName + "/" + deptName);
        }
    }

    // ── 六维度评分 ────────────────────────────────────────────────────────────

    private void fillScores(EmployeePortraitVO vo, String personName, String beginTime, String endTime) {
        // 加载全部事件，按姓名 LIKE 过滤（支持逗号分隔多人）
        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);

        // 精确匹配（防止逗号多人字段的误匹配）
        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");
        dq.setOrg(ScoreLevelEnum.PERSON.getCode());
        List<ScoreDimension> dims = scoreDimensionMapper.selectList(dq);
        dims.sort(Comparator.comparing(d -> d.getSortOrder() == null ? 999 : d.getSortOrder()));

        List<EmployeePortraitVO.DimScoreItem> items = new ArrayList<>();
        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);

            EmployeePortraitVO.DimScoreItem item = new EmployeePortraitVO.DimScoreItem();
            item.setName(dim.getName());
            item.setScore(dimScore.setScale(1, RoundingMode.HALF_UP));
            item.setWeight(weight);
            item.setBaseScore(base);
            item.setEventScore(eventScore.setScale(2, RoundingMode.HALF_UP));
            items.add(item);
        }

        vo.setDimensions(items);
        vo.setTotalScore(total.setScale(1, RoundingMode.HALF_UP));
    }

    // ── 考试成绩 ──────────────────────────────────────────────────────────────

    private void fillExamScore(EmployeePortraitVO vo, String personName) {
        LedgerExamScore q = new LedgerExamScore();
        q.setPersonName(personName);
        List<LedgerExamScore> list = ledgerExamScoreMapper.selectList(q);
        if (list == null || list.isEmpty()) return;
        list.sort((a, b) -> {
            if (a.getExamDate() == null) return 1;
            if (b.getExamDate() == null) return -1;
            return b.getExamDate().compareTo(a.getExamDate());
        });
        LedgerExamScore exam = list.get(0);
        vo.setTheoryScore(exam.getTheoryScore());
        vo.setImageScore(exam.getImageScore());
        vo.setExamDate(exam.getExamDate());
        vo.setExamCategory(exam.getExamCategory());
        vo.setExamPeriod(exam.getExamPeriod());
    }

    // ── 获奖记录 ──────────────────────────────────────────────────────────────

    private void fillScoreDetails(EmployeePortraitVO vo, String personName, String beginTime, String endTime) {
        ScoreEvent eq = new ScoreEvent();
        eq.setPersonName(personName);
        if (beginTime != null && !beginTime.isEmpty()) eq.getParams().put("beginTime", beginTime);
        if (endTime   != null && !endTime.isEmpty())   eq.getParams().put("endTime",   endTime);
        List<ScoreEvent> events = scoreEventMapper.selectList(eq);

        List<EmployeePortraitVO.ScoreDetail> details = new ArrayList<>();
        for (ScoreEvent e : events) {
            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;

            EmployeePortraitVO.ScoreDetail d = new EmployeePortraitVO.ScoreDetail();
            d.setDimensionName(e.getDimensionName());
            d.setLevel2Name(e.getLevel2Name());
            d.setLevel3Name(e.getLevel3Name());
            d.setTotalScore(e.getTotalScore());
            details.add(d);
        }
        vo.setScoreDetails(details);
    }

    private void fillAwards(EmployeePortraitVO vo, String personName) {
        // 群团协作能力 dimension_id = 5
        ScoreEvent eq = new ScoreEvent();
        eq.setPersonName(personName);
        eq.setDimensionId(5L);
        List<ScoreEvent> events = scoreEventMapper.selectList(eq);

        List<EmployeePortraitVO.AwardRecord> awards = new ArrayList<>();
        for (ScoreEvent e : events) {
            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;

            EmployeePortraitVO.AwardRecord ar = new EmployeePortraitVO.AwardRecord();
            ar.setLevel3Name(e.getLevel3Name());
            ar.setLevel2Name(e.getLevel2Name());
            ar.setLevel4Name(e.getLevel4Name());
            ar.setScore(e.getTotalScore());
            awards.add(ar);
        }
        vo.setAwards(awards);
    }

    // ── 枚举解码工具 ─────────────────────────────────────────────────────────

    private static String decodeQualLevel(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;
        }
    }

    private static String decodePolitical(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 static String decodeChar(String v) {
        if (v == null) return "";
        // 值格式如 "ISTJ"，映射为 "ISTJ（检查员型）"
        Map<String, String> m = new LinkedHashMap<>();
        m.put("ISTJ", "ISTJ（检查员型）"); m.put("ISFJ", "ISFJ（守护者型）");
        m.put("INFJ", "INFJ（咨询师型）"); m.put("INTJ", "INTJ（战略家型）");
        m.put("ISTP", "ISTP（手艺人型）"); m.put("ISFP", "ISFP（艺术家型）");
        m.put("INFP", "INFP（调停者型）"); m.put("INTP", "INTP（逻辑学家型）");
        m.put("ESTP", "ESTP（企业家型）"); m.put("ESFP", "ESFP（表演者型）");
        m.put("ENFP", "ENFP（活动家型）"); m.put("ENTP", "ENTP（辩论家型）");
        m.put("ESTJ", "ESTJ（总经理型）"); m.put("ESFJ", "ESFJ（执政官型）");
        m.put("ENFJ", "ENFJ（教育家型）"); m.put("ENTJ", "ENTJ（指挥官型）");
        return m.getOrDefault(v, v);
    }

    private static String decodeWorkStyle(String v) {
        if (v == null) return "";
        switch (v) {
            case "D": return "D型（支配型）";
            case "I": return "I型（影响型）";
            case "S": return "S型（稳健型）";
            case "C": return "C型（尽责型）";
            default:  return v;
        }
    }
}
