package com.cmvr.evaluation.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.cmvr.evaluation.mapper.AeIndicatorMapper;
import com.cmvr.evaluation.model.domain.AeIndicatorEntity;
import com.cmvr.evaluation.model.dto.AeIndicatorCreateDTO;
import com.cmvr.evaluation.model.dto.AeIndicatorUpdateDTO;
import com.cmvr.evaluation.service.AeIndicatorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class AeIndicatorServiceImpl extends ServiceImpl<AeIndicatorMapper, AeIndicatorEntity> implements AeIndicatorService {

    @Override
    public boolean saveIndicator(AeIndicatorCreateDTO createDTO) {
        // 1. DTO 转 Entity
        AeIndicatorEntity entity = CreateDTOConvertToEntity(createDTO);
        // 3. 调用MyBatis-Plus父类方法完成新增，返回执行结果
        boolean saveResult = this.save(entity);
        // 4. 日志记录：新增结果（成功/失败）
        if (saveResult) {
            log.info("评价管理---指标库---新增指标成功，指标名称：{}，层级：{}", entity.getName(), entity.getLevel());
        } else {
            log.error("评价管理---指标库---新增指标失败，指标名称：{}，层级：{}", entity.getName(), entity.getLevel());
        }
        return saveResult;
    }


    @Override
    public List<AeIndicatorEntity> selectIndicatorByParentId(Long parentId, Integer type) {
        log.info("评价管理---指标库---开始按父id查询指标，查询父id：{}", parentId == null ? "所有数据" : parentId);

        LambdaQueryWrapper<AeIndicatorEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(parentId != null, AeIndicatorEntity::getParentId, parentId)
                .eq(type != null, AeIndicatorEntity::getType, type)
                .orderByAsc(AeIndicatorEntity::getSort);
        List<AeIndicatorEntity> list = this.list(queryWrapper);
        // 3. 日志记录：查询结果
        log.info("评价管理---指标库---按父id查询指标完成，查询id：{}，返回数量：{}",
                parentId == null ? "所有数据" : parentId, list.size());
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 事务控制：所有异常都回滚，保证原子性
    public boolean removeIndicator(Long id) {
        // 1. 参数校验：ID不能为空
        Assert.notNull(id, "级联删除指标失败：待删除指标ID不能为空");
        log.info("开始级联删除指标，主指标ID：{}", id);
        // 2. 递归查询所有后代指标ID（子/孙级，无论多少级）
        List<Long> allDeleteIds = new ArrayList<>();
        findAllChildrenIds(id, allDeleteIds); // 收集所有后代ID
        // 3. 合并删除ID：添加当前指标ID（删自身+后代）
        allDeleteIds.add(id);
        log.info("级联删除准备完成，主指标ID：{}，需删除后代数量：{}，总删除数量：{}",
                id, allDeleteIds.size() - 1, allDeleteIds.size());

        // 4. 批量删除：一次执行，效率高（适配逻辑删除/物理删除，MP自动处理）
        if (CollectionUtils.isEmpty(allDeleteIds)) {
            log.warn("级联删除指标无数据可删，主指标ID：{}", id);
            return false;
        }
        boolean deleteResult = this.removeByIds(allDeleteIds);

        // 5. 日志记录删除结果
        if (deleteResult) {
            log.info("级联删除指标成功，主指标ID：{}，成功删除数量：{}", id, allDeleteIds.size());
        } else {
            log.error("级联删除指标失败，主指标ID：{}，待删除ID集合：{}", id, allDeleteIds);
        }
        return deleteResult;
    }

    @Override
    public boolean updateIndicator(AeIndicatorUpdateDTO dto) {
        // 1. 验证数据是否存在
        AeIndicatorEntity existEntity = this.getById(dto.getId());
        if (existEntity == null) {
            log.error("评价管理---指标库---修改指标失败，指标ID {} 不存在", dto.getId());
            return false;
        }
        AeIndicatorEntity entity = updateDTOConvertToEntity(dto);
        System.out.println("entity = " + entity);
        boolean saveResult = this.updateById(entity);
        // 4. 日志记录：新增结果（成功/失败）
        if (saveResult) {
            log.info("评价管理---指标库---修改指标成功，指标名称：{}", entity.getName());
        } else {
            log.error("评价管理---指标库---修改指标失败，指标名称：{}", entity.getName());
        }
        return saveResult;
    }

    @Override
    public List<AeIndicatorEntity> getChildrenByParentIdWithLevelLimit(Long parentId, Integer maxLevel, Integer type) {
        // 1. 参数校验与默认值处理：避免空指针，适配业务默认规则
        if (parentId == null) {
            parentId = 0L; // 默认查父ID为0的根节点（一级指标）
        }
        if (maxLevel == null || maxLevel < 1) {
            maxLevel = 3; // 默认最大层级为3，贴合三级指标业务
        }
        if (type == null) {
            return new ArrayList<>(); // 类型为null时，无数据可查，返回空列表
        }

        Integer currentLevel = 1;
        return buildTree(parentId, currentLevel, maxLevel, type);
    }

    @Override
    public List<AeIndicatorEntity> getChildrenByIndicatorIdWithLevel(Long indicatorId, Integer level, Integer type) {
        LambdaQueryWrapper<AeIndicatorEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AeIndicatorEntity::getParentId, indicatorId)
                .eq(AeIndicatorEntity::getLevel, level)
                .eq(AeIndicatorEntity::getType, type);
        return this.list(wrapper);
    }

    /**
     * 私有工具方法：递归查询指定ID的所有后代指标ID（子→孙→重孙，无限级）
     *
     * @param parentId    父/祖指标ID
     * @param childrenIds 用于收集所有后代ID的集合（引用传递）
     */
    private void findAllChildrenIds(Long parentId, List<Long> childrenIds) {
        // ① 查询当前parentId的直接子指标ID
        LambdaQueryWrapper<AeIndicatorEntity> queryWrapper = new LambdaQueryWrapper<AeIndicatorEntity>()
                .select(AeIndicatorEntity::getId) // 仅查ID字段，减少数据传输
                .eq(AeIndicatorEntity::getParentId, parentId);

        // 核心修正：使用MP双参数listObjs，直接Object转Long，无多余参数
        List<Long> directChildIds = this.listObjs(
                queryWrapper,
                // 转换器：将查询到的Object类型ID，直接强转为Long（数据库ID为数值型，安全转换）
                obj -> Long.parseLong(obj.toString())
        );

        // ② 无直接子节点，递归终止
        if (CollectionUtils.isEmpty(directChildIds)) {
            return;
        }

        // ③ 将直接子ID加入集合，再递归查询每个子ID的后代ID
        childrenIds.addAll(directChildIds);
        for (Long childId : directChildIds) {
            findAllChildrenIds(childId, childrenIds); // 递归：查子节点的子节点
        }
    }

    private AeIndicatorEntity CreateDTOConvertToEntity(AeIndicatorCreateDTO dto) {
        if (dto == null) {
            return null;
        }

        AeIndicatorEntity entity = new AeIndicatorEntity();
        entity.setParentId(dto.getParentId());
        entity.setLevel(dto.getLevel());
        entity.setName(dto.getName());
        entity.setCompareNum1(dto.getCompareNum1());
        entity.setSymbol(dto.getSymbol());
        entity.setCompareNum2(dto.getCompareNum2());
        entity.setScore(dto.getScore());
        entity.setWeight(dto.getWeight());
        entity.setRemark(dto.getRemark());
        entity.setSort(dto.getSort());
        entity.setType(dto.getType());

        return entity;
    }

    private AeIndicatorEntity updateDTOConvertToEntity(AeIndicatorUpdateDTO dto) {
        if (dto == null) {
            return null;
        }

        AeIndicatorEntity entity = new AeIndicatorEntity();
        entity.setId(dto.getId()); // 重要：必须设置ID
        entity.setParentId(dto.getParentId());
        entity.setName(dto.getName());

        // 只更新必要的字段，不要清空其他字段
        if (dto.getLevel() != null) {
            entity.setLevel(dto.getLevel());
        }
        if (dto.getCompareNum1() != null) {
            entity.setCompareNum1(dto.getCompareNum1());
        }
        if (dto.getSymbol() != null) {
            entity.setSymbol(dto.getSymbol());
        }
        if (dto.getCompareNum2() != null) {
            entity.setCompareNum2(dto.getCompareNum2());
        }
        if (dto.getScore() != null) {
            entity.setScore(dto.getScore());
        }
        if (dto.getWeight() != null) {
            entity.setWeight(dto.getWeight());
        }
        if (dto.getRemark() != null) {
            entity.setRemark(dto.getRemark());
        }
        if (dto.getSort() != null) {
            entity.setSort(dto.getSort());
        }
        if (dto.getType() != null) {
            entity.setType(dto.getType());
        }

        return entity;
    }

    /**
     * 私有递归辅助方法：核心构建树形结构，实现层级限制
     *
     * @param parentId     当前父节点ID
     * @param currentLevel 当前要构建的节点层级
     * @param maxLevel     允许的最大层级（达到则停止递归）
     * @param type         指标类型 0-语音 1-触控
     * @return 带children的树形节点列表
     */
    private List<AeIndicatorEntity> buildTree(Long parentId, Integer currentLevel, Integer maxLevel, Integer type) {
        // 3. 构建Lambda查询条件：类型过滤+父ID匹配+逻辑删除过滤+按sort降序
        LambdaQueryWrapper<AeIndicatorEntity> queryWrapper = new LambdaQueryWrapper<AeIndicatorEntity>()
                .eq(AeIndicatorEntity::getParentId, parentId) // 匹配当前父ID
                .eq(AeIndicatorEntity::getType, type); // 过滤指标类型

        // 4. 查询当前父ID下的直接子节点
        List<AeIndicatorEntity> childNodes = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(childNodes)) {
            return new ArrayList<>(); // 无直接子节点，返回空列表，递归终止
        }

        // 5. 遍历子节点，递归构建子节点的children（层级未达最大值时才递归）
        for (AeIndicatorEntity node : childNodes) {
            // 核心：判断当前节点层级是否小于最大层级，未达则继续递归查询子节点的子节点
            if (currentLevel < maxLevel) {
                // 递归：当前节点作为父ID，层级+1，继续构建子树
                List<AeIndicatorEntity> grandChildren = buildTree(node.getId(), currentLevel + 1, maxLevel, type);
                node.setChildren(grandChildren); // 给当前节点设置子节点列表
            } else {
                node.setChildren(new ArrayList<>()); // 达到最大层级，子节点置空，停止递归
            }
        }

        // 6. 返回当前层级的带children的节点列表
        return childNodes;
    }

}
