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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sundot.airport.common.config.LevelConfig;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.system.domain.BasePerformanceIndicator;
import com.sundot.airport.system.domain.BasePerformanceIndicatorCategoryTreeDTO;
import com.sundot.airport.system.domain.BasePerformanceIndicatorCategoryTreeRequestDTO;
import com.sundot.airport.system.service.IBasePerformanceIndicatorService;
import com.sundot.airport.system.utils.CodeGeneratorUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sundot.airport.system.mapper.BasePerformanceIndicatorCategoryMapper;
import com.sundot.airport.system.domain.BasePerformanceIndicatorCategory;
import com.sundot.airport.system.service.IBasePerformanceIndicatorCategoryService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * 考核指标分类Service业务层处理
 *
 * @author ruoyi
 * @date 2026-04-28
 */
@Service
public class BasePerformanceIndicatorCategoryServiceImpl implements IBasePerformanceIndicatorCategoryService {
    @Autowired
    private BasePerformanceIndicatorCategoryMapper basePerformanceIndicatorCategoryMapper;
    @Autowired
    private LevelConfig levelConfig;
    @Autowired
    private CodeGeneratorUtil codeGeneratorUtil;
    @Autowired
    private IBasePerformanceIndicatorService basePerformanceIndicatorService;

    /**
     * 查询考核指标分类
     *
     * @param id 考核指标分类主键
     * @return 考核指标分类
     */
    @Override
    public BasePerformanceIndicatorCategory selectBasePerformanceIndicatorCategoryById(Long id) {
        return basePerformanceIndicatorCategoryMapper.selectBasePerformanceIndicatorCategoryById(id);
    }

    /**
     * 查询考核指标分类列表
     *
     * @param basePerformanceIndicatorCategory 考核指标分类
     * @return 考核指标分类
     */
    @Override
    public List<BasePerformanceIndicatorCategory> selectBasePerformanceIndicatorCategoryList(BasePerformanceIndicatorCategory basePerformanceIndicatorCategory) {
        return basePerformanceIndicatorCategoryMapper.selectBasePerformanceIndicatorCategoryList(basePerformanceIndicatorCategory);
    }

    /**
     * 新增考核指标分类
     *
     * @param basePerformanceIndicatorCategory 考核指标分类
     * @return 结果
     */
    @Override
    public int insertBasePerformanceIndicatorCategory(BasePerformanceIndicatorCategory basePerformanceIndicatorCategory) {
        basePerformanceIndicatorCategory.setCreateTime(DateUtils.getNowDate());
        if (ObjectUtil.isEmpty(basePerformanceIndicatorCategory.getParentId()) || basePerformanceIndicatorCategory.getParentId().equals(0L)) {
            basePerformanceIndicatorCategory.setAncestors("0");
            basePerformanceIndicatorCategory.setLevel(1);
        } else {
            BasePerformanceIndicatorCategory info = basePerformanceIndicatorCategoryMapper.selectBasePerformanceIndicatorCategoryById(basePerformanceIndicatorCategory.getParentId());
            if (ObjectUtil.isEmpty(info)) {
                throw new ServiceException("父分类不存在，不允许新增");
            }
            basePerformanceIndicatorCategory.setAncestors(info.getAncestors() + "," + basePerformanceIndicatorCategory.getParentId());
            basePerformanceIndicatorCategory.setLevel(basePerformanceIndicatorCategory.getAncestors().split(",").length);
        }
        verifyData(basePerformanceIndicatorCategory);
        basePerformanceIndicatorCategory.setCode(codeGeneratorUtil.getNextCodeGenerator());
        return basePerformanceIndicatorCategoryMapper.insertBasePerformanceIndicatorCategory(basePerformanceIndicatorCategory);
    }

    /**
     * 修改考核指标分类
     *
     * @param basePerformanceIndicatorCategory 考核指标分类
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateBasePerformanceIndicatorCategory(BasePerformanceIndicatorCategory basePerformanceIndicatorCategory) {
        basePerformanceIndicatorCategory.setUpdateTime(DateUtils.getNowDate());
        BasePerformanceIndicatorCategory newParent = basePerformanceIndicatorCategoryMapper.selectBasePerformanceIndicatorCategoryById(basePerformanceIndicatorCategory.getParentId());
        BasePerformanceIndicatorCategory old = basePerformanceIndicatorCategoryMapper.selectBasePerformanceIndicatorCategoryById(basePerformanceIndicatorCategory.getId());
        if (ObjectUtils.isNotEmpty(newParent) && ObjectUtils.isNotEmpty(old)) {
            String newAncestors = newParent.getAncestors() + "," + newParent.getId();
            String oldAncestors = old.getAncestors();
            basePerformanceIndicatorCategory.setAncestors(newAncestors);
            basePerformanceIndicatorCategory.setLevel(basePerformanceIndicatorCategory.getAncestors().split(",").length);
            updateChildren(basePerformanceIndicatorCategory.getId(), newAncestors, oldAncestors);
        }
        verifyData(basePerformanceIndicatorCategory);
        return basePerformanceIndicatorCategoryMapper.updateBasePerformanceIndicatorCategory(basePerformanceIndicatorCategory);
    }

    /**
     * 修改子元素关系
     *
     * @param id           被修改的元素ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    private void updateChildren(Long id, String newAncestors, String oldAncestors) {
        List<BasePerformanceIndicatorCategory> children = basePerformanceIndicatorCategoryMapper.selectChildrenById(id);
        for (BasePerformanceIndicatorCategory child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
            child.setLevel(child.getAncestors().split(",").length);
            verifyData(child);
        }
        if (!CollectionUtils.isEmpty(children)) {
            basePerformanceIndicatorCategoryMapper.updateChildren(children);
        }
    }

    /**
     * 批量删除考核指标分类
     *
     * @param ids 需要删除的考核指标分类主键
     * @return 结果
     */
    @Override
    public int deleteBasePerformanceIndicatorCategoryByIds(Long[] ids) {
        return basePerformanceIndicatorCategoryMapper.deleteBasePerformanceIndicatorCategoryByIds(ids);
    }

    /**
     * 删除考核指标分类信息
     *
     * @param id 考核指标分类主键
     * @return 结果
     */
    @Override
    public int deleteBasePerformanceIndicatorCategoryById(Long id) {
        return basePerformanceIndicatorCategoryMapper.deleteBasePerformanceIndicatorCategoryById(id);
    }

    /**
     * 查询考核指标分类对象树形结构
     *
     * @param basePerformanceIndicatorCategory 考核指标分类对象
     * @return 树结构列表
     */
    @Override
    public List<BasePerformanceIndicatorCategory> selectBasePerformanceIndicatorCategoryListTree(BasePerformanceIndicatorCategory basePerformanceIndicatorCategory) {
        List<BasePerformanceIndicatorCategory> list = selectBasePerformanceIndicatorCategoryList(basePerformanceIndicatorCategory);
        return buildTree(list);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param list 列表
     * @return 树结构列表
     */
    @Override
    public List<BasePerformanceIndicatorCategory> buildTree(List<BasePerformanceIndicatorCategory> list) {
        // 结果列表
        List<BasePerformanceIndicatorCategory> result = new ArrayList<>();

        // 临时Map，用于快速查找节点
        Map<Long, BasePerformanceIndicatorCategory> nodeMap = new HashMap<>();

        // 第一次遍历：将所有节点存入Map
        for (BasePerformanceIndicatorCategory node : list) {
            nodeMap.put(node.getId(), node);
        }

        // 第二次遍历：建立父子关系
        for (BasePerformanceIndicatorCategory node : list) {
            Long parentId = node.getParentId();
            if (parentId == null || parentId == 0L) {
                // 父ID为null或0，说明是根节点
                result.add(node);
            } else {
                // 查找父节点
                BasePerformanceIndicatorCategory parent = nodeMap.get(parentId);
                if (parent != null) {
                    // 初始化子节点列表
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    // 将当前节点添加到父节点的子列表中
                    List<BasePerformanceIndicatorCategory> children = (List<BasePerformanceIndicatorCategory>) parent.getChildren();
                    children.add(node);
                }
            }
        }

        return result;
    }

    /**
     * 验证数据
     */
    private void verifyData(BasePerformanceIndicatorCategory basePerformanceIndicatorCategory) {
        if (basePerformanceIndicatorCategory.getLevel() > levelConfig.getPerformanceIndicatorCategoryLevel()) {
            throw new ServiceException("操作失败,层级超过限制" + levelConfig.getPerformanceIndicatorCategoryLevel() + "级");
        }
    }

    /**
     * 获取分类树及关联指标（支持模糊查询）
     *
     * @param requestDTO 入参
     * @return 树结构列表
     */
    @Override
    public List<BasePerformanceIndicatorCategoryTreeDTO> getCategoryTreeWithIndicatorList(BasePerformanceIndicatorCategoryTreeRequestDTO requestDTO) {

        // 1. 查询所有分类
        List<BasePerformanceIndicatorCategory> allCategorieList = basePerformanceIndicatorCategoryMapper.selectBasePerformanceIndicatorCategoryList(new BasePerformanceIndicatorCategory());

        // 2. 查询指标（支持指标名称模糊匹配）
        BasePerformanceIndicator indicator = new BasePerformanceIndicator();
        indicator.setName(requestDTO.getIndicatorName());
        List<BasePerformanceIndicator> indicatorList = basePerformanceIndicatorService.selectBasePerformanceIndicatorList(indicator);

        // 3. 按分类编码分组指标
        Map<String, List<BasePerformanceIndicator>> indicatorMap = indicatorList.stream().collect(Collectors.groupingBy(BasePerformanceIndicator::getCategoryCode));

        // 4. 转换为DTO并绑定指标
        Map<Long, BasePerformanceIndicatorCategoryTreeDTO> dtoMap = new HashMap<>();
        for (BasePerformanceIndicatorCategory category : allCategorieList) {
            BasePerformanceIndicatorCategoryTreeDTO dto = BasePerformanceIndicatorCategoryTreeDTO.fromEntity(category);
            List<BasePerformanceIndicator> list = indicatorMap.get(category.getCode());
            dto.setIndicatorList(list != null ? list : Collections.emptyList());
            dtoMap.put(dto.getId(), dto);
        }

        // 5. 构建树形结构
        List<BasePerformanceIndicatorCategoryTreeDTO> rootList = new ArrayList<>();
        for (BasePerformanceIndicatorCategoryTreeDTO dto : dtoMap.values()) {
            Long parentId = dto.getParentId();
            if (parentId == null || parentId == 0) {
                rootList.add(dto);
            } else {
                BasePerformanceIndicatorCategoryTreeDTO parent = dtoMap.get(parentId);
                if (parent != null) {
                    parent.getChildren().add(dto);
                }
            }
        }

        // 6. 递归过滤（分类条件 + 指标条件）
        List<BasePerformanceIndicatorCategoryTreeDTO> filteredRootList = filterTree(rootList, requestDTO);

        // 7. 排序
        sortChildren(filteredRootList);

        return filteredRootList;
    }

    /**
     * 递归过滤树节点
     */
    private List<BasePerformanceIndicatorCategoryTreeDTO> filterTree(List<BasePerformanceIndicatorCategoryTreeDTO> nodeList, BasePerformanceIndicatorCategoryTreeRequestDTO requestDTO) {
        List<BasePerformanceIndicatorCategoryTreeDTO> result = new ArrayList<>();
        for (BasePerformanceIndicatorCategoryTreeDTO node : nodeList) {
            // 判断是否为一级分类（parentId = 0 或 null）
            boolean isRoot = node.getParentId() == null || node.getParentId() == 0;

            // 递归过滤子节点
            List<BasePerformanceIndicatorCategoryTreeDTO> filteredChildren = filterTree(node.getChildren(), requestDTO);

            if (isRoot) {
                // 一级分类：只有当它有有效的二级子节点时才保留
                if (!filteredChildren.isEmpty()) {
                    node.setChildren(filteredChildren);
                    result.add(node);
                }
                // 如果没有有效的二级子节点，直接丢弃一级分类
            } else {
                // 二级分类：必须满足以下条件之一才能保留：
                // 1. 自身匹配（分类名称/编码）
                // 2. 有指标数据（indicatorList不为空）
                boolean selfMatch = matchesCategory(node, requestDTO);
                boolean hasIndicators = node.getIndicatorList() != null && !node.getIndicatorList().isEmpty();

                // 如果查询条件为空，则只要有指标就显示
                // 如果查询条件不为空，则需要满足查询条件或有指标
                boolean shouldKeep = false;
                if (StrUtil.isBlank(requestDTO.getCategoryCode()) && StrUtil.isBlank(requestDTO.getCategoryName())) {
                    // 没有分类查询条件时，只要有指标就保留
                    shouldKeep = hasIndicators;
                } else {
                    // 有分类查询条件时，需要自身匹配或有指标
                    shouldKeep = selfMatch || hasIndicators;
                }

                if (shouldKeep) {
                    node.setChildren(filteredChildren);
                    result.add(node);
                }
            }
        }
        return result;
    }

    /**
     * 匹配分类
     */
    private boolean matchesCategory(BasePerformanceIndicatorCategoryTreeDTO dto, BasePerformanceIndicatorCategoryTreeRequestDTO requestDTO) {
        boolean match = true;
        if (StrUtil.isNotBlank(requestDTO.getCategoryCode())) {
            match = match && requestDTO.getCategoryCode().equals(dto.getCode());
        }
        if (StrUtil.isNotBlank(requestDTO.getCategoryName())) {
            match = match && StrUtil.containsIgnoreCase(dto.getName(), requestDTO.getCategoryName());
        }
        return match;
    }

    /**
     * 排序子节点
     */
    private void sortChildren(List<BasePerformanceIndicatorCategoryTreeDTO> list) {
        if (list == null) {
            return;
        }
        list.sort(Comparator.comparing(BasePerformanceIndicatorCategoryTreeDTO::getOrderNum, Comparator.nullsLast(Integer::compareTo)));
        for (BasePerformanceIndicatorCategoryTreeDTO dto : list) {
            sortChildren(dto.getChildren());
        }
    }
}
