package com.hotent.baseInfo.manager.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hotent.base.exception.BaseException;
import com.hotent.baseInfo.dto.CatalogStatusDto;
import com.hotent.baseInfo.dto.CategoryCreateDto;
import com.hotent.baseInfo.dto.ContentCreateDto;
import com.hotent.baseInfo.model.CostCatalog;
import com.hotent.baseInfo.dao.CostCatalogDao;
import com.hotent.baseInfo.manager.CostCatalogManager;
import com.hotent.baseInfo.req.CostCatalogPageReq;
import com.hotent.base.manager.impl.BaseManagerImpl;
import com.hotent.constant.BaseConstant;
import com.hotent.uc.api.model.IUser;
import com.hotent.uc.manager.UserManager;
import com.hotent.uc.model.User;
import com.hotent.uc.util.ContextUtil;
import com.hotent.util.CopyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


import com.hotent.base.util.StringUtil;

/**
 * 成本监审目录表 服务实现类
 *
 * @author 超级管理员
 * @since 2025-09-04
 */
@Service
public class CostCatalogManagerImpl extends BaseManagerImpl<CostCatalogDao, CostCatalog> implements CostCatalogManager {

    @Autowired
    private UserManager userService;


    @Override
    public CostCatalog getDetail(String id) {
        CostCatalog costCatalog = this.get(id);
        return costCatalog;
    }


//    @Override
//    public List<CostCatalog> getCatalogList(CostCatalogPageReq req) {
//        // 构建查询条件
//        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(CostCatalog::getIsDeleted, "0");
//        // 根据查询条件过滤
//        if (StringUtil.isNotEmpty(req.getCategoryId())) {
//            queryWrapper.eq(CostCatalog::getParentId, req.getCategoryId());
//        }
//
//        if (StringUtil.isNotEmpty(req.getAuditType())) {
//            String[] auditTypes = req.getAuditType().split(",");
//
//            queryWrapper.in(CostCatalog::getAuditType, Arrays.asList(auditTypes));
//        }
//        if (StringUtil.isNotEmpty(req.getKeyword())) {
//            queryWrapper.like(CostCatalog::getCatalogName, req.getKeyword());
//        }
//        return this.list(queryWrapper);
//    }

    @Override
    public List<CostCatalog> getCatalogList(CostCatalogPageReq req) throws Exception {
        // 获取所有未删除的数据
        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, "0");
        if (StringUtil.isNotEmpty(req.getCategoryId())) {
            queryWrapper.eq(CostCatalog::getCatalogId, req.getCategoryId());
        }
        if (StringUtil.isNotEmpty(req.getAuditType())) {
            queryWrapper.in(CostCatalog::getAuditType, Arrays.asList(req.getAuditType().split(",")));
        }
        if (StringUtil.isNotEmpty(req.getCatalogName())) {
            queryWrapper.like(CostCatalog::getCatalogName, req.getCatalogName());
        }

        IUser iUser = ContextUtil.getCurrentUser();
        User user = userService.getByAccount(iUser.getAccount());
        if (user!=null) {
            queryWrapper.like(CostCatalog::getPriceLevel,user.getDataScope());
        }
        List<CostCatalog> allCatalogs = this.list(queryWrapper);
//
//        // 如果没有查询条件，返回所有数据
//        if (StringUtil.isEmpty(req.getCategoryId()) &&
//                StringUtil.isEmpty(req.getAuditType()) &&
//                StringUtil.isEmpty(req.getCatalogName())) {
//            return allCatalogs;
//        }
//
//        // 根据条件筛选出匹配的节点
//        List<CostCatalog> matchedCatalogs = allCatalogs.stream()
//                .filter(catalog -> matchesConditions(catalog, req))
//                .collect(Collectors.toList());
//
//        // 如果没有匹配的节点，直接返回空列表
//        if (matchedCatalogs.isEmpty()) {
//            return matchedCatalogs;
//        }
//
//        // 构建包含所有匹配节点、父节点和子节点的完整集合
//        Set<String> neededIds = new HashSet<>();
//        Map<String, CostCatalog> catalogMap = allCatalogs.stream()
//                .collect(Collectors.toMap(CostCatalog::getCatalogId, Function.identity()));
//
//        // 按父节点分组，便于查找子节点
//        Map<String, List<CostCatalog>> parentChildMap = allCatalogs.stream()
//                .collect(Collectors.groupingBy(CostCatalog::getParentId));
//
//        // 将匹配的节点加入集合
//        for (CostCatalog catalog : matchedCatalogs) {
//            neededIds.add(catalog.getCatalogId());
//            // 反推父节点
//            addParentNodes(catalog, catalogMap, neededIds);
//            // 向下查找子节点
//            addChildNodes(catalog, parentChildMap, neededIds);
//        }

        // 返回包含所有需要节点的列表
//        return allCatalogs.stream()
//                .filter(catalog -> neededIds.contains(catalog.getCatalogId()))
//                .collect(Collectors.toList());
        return allCatalogs;
    }

    // 匹配条件的方法
    private boolean matchesConditions(CostCatalog catalog, CostCatalogPageReq req) {
        // 父节点ID过滤
        if (StringUtil.isNotEmpty(req.getCategoryId()) &&
                !req.getCategoryId().equals(catalog.getParentId())) {
            return false;
        }

        // 审核类型过滤（支持多个值，以逗号分隔）
        if (StringUtil.isNotEmpty(req.getAuditType())) {
            String[] searchTypes = req.getAuditType().split(",");
            String catalogAuditType = catalog.getAuditType();

            if (StringUtil.isEmpty(catalogAuditType)) {
                return false;
            }

            // 将目录的审核类型按逗号分割为集合
            Set<String> catalogTypes = Arrays.stream(catalogAuditType.split(","))
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .collect(Collectors.toSet());

            // 检查是否有匹配的审核类型
            boolean hasMatch = Arrays.stream(searchTypes)
                    .map(String::trim)
                    .filter(s -> !s.isEmpty())
                    .anyMatch(catalogTypes::contains);

            if (!hasMatch) {
                return false;
            }
        }

        // 关键字过滤（目录名称）
        if (StringUtil.isNotEmpty(req.getCatalogName()) &&
                (StringUtil.isEmpty(catalog.getCatalogName()) ||
                        !catalog.getCatalogName().contains(req.getCatalogName()))) {
            return false;
        }

        return true;
    }

    // 递归添加父节点
    private void addParentNodes(CostCatalog catalog, Map<String, CostCatalog> catalogMap, Set<String> neededIds) {
        String parentId = catalog.getParentId();
        // 如果父节点ID不为空且不是根节点"0"
        if (StringUtil.isNotEmpty(parentId) && !"0".equals(parentId)) {
            // 如果该父节点还没有加入集合
            if (!neededIds.contains(parentId)) {
                neededIds.add(parentId);
                // 继续向上查找父节点
                CostCatalog parentCatalog = catalogMap.get(parentId);
                if (parentCatalog != null) {
                    addParentNodes(parentCatalog, catalogMap, neededIds);
                }
            }
        }
    }

    // 递归添加子节点
    private void addChildNodes(CostCatalog catalog, Map<String, List<CostCatalog>> parentChildMap, Set<String> neededIds) {
        String catalogId = catalog.getCatalogId();
        // 查找当前节点的子节点
        List<CostCatalog> children = parentChildMap.get(catalogId);
        if (children != null && !children.isEmpty()) {
            for (CostCatalog child : children) {
                // 如果子节点还没有加入集合
                if (!neededIds.contains(child.getCatalogId())) {
                    neededIds.add(child.getCatalogId());
                    // 递归查找子节点的子节点
                    addChildNodes(child, parentChildMap, neededIds);
                }
            }
        }
    }


    @Override
    public void createCategory(CategoryCreateDto createDto) {
        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getCatalogId, createDto.getParentId());
        CostCatalog costCatalog = this.getOne(queryWrapper, false);
        if (costCatalog == null) {
            throw new BaseException("父节点不存在");
        }
        if (costCatalog.getNodeType().equals(BaseConstant.CATALOG_TYPE_NR)) {
            throw new BaseException("父节点不能为内容节点");
        }
        CostCatalog catalog = CopyUtil.copy(createDto, CostCatalog.class);
        catalog.setCode(generateNewCode(costCatalog.getCatalogId()));
        catalog.setParentId(costCatalog.getCatalogId());
        catalog.setNodeType(createDto.getNodeType());
        catalog.setCreateTime(LocalDateTime.now());
        catalog.setCreateBy(ContextUtil.getCurrentUser().getAccount());
        catalog.setLayerLevel(costCatalog.getLayerLevel() + "," + catalog.getParentId());
        this.save(catalog);
    }

    @Override
    public void createContent(ContentCreateDto createDto) {
        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getCatalogId, createDto.getParentId());
        CostCatalog costCatalog = this.getOne(queryWrapper, false);
        if (costCatalog == null) {
            throw new BaseException("父节点不存在");
        }
        if (costCatalog.getNodeType().equals(BaseConstant.CATALOG_TYPE_NR)) {
            throw new BaseException("父节点不能为内容节点");
        }

        CostCatalog catalog = CopyUtil.copy(createDto, CostCatalog.class);
        catalog.setCode(generateNewCode(costCatalog.getCatalogId()));
        catalog.setNodeType(BaseConstant.CATALOG_TYPE_NR);
        catalog.setCreateTime(LocalDateTime.now());
        catalog.setCreateBy(ContextUtil.getCurrentUser().getAccount());
        catalog.setNodeType(createDto.getNodeType());
        catalog.setLayerLevel(costCatalog.getLayerLevel() + "," + catalog.getParentId());
        this.save(catalog);
    }

    @Override
    public boolean updateStatus(CatalogStatusDto statusDto) {
        CostCatalog catalog = this.getById(statusDto.getId());
        if (catalog == null) {
            throw new BaseException("目录节点不存在");
        }
        if (BaseConstant.DELETE_FLAG.equals(catalog.getIsDeleted())) {
            throw new BaseException("目录节点不存在");
        }
        catalog.setStatus(statusDto.getStatus());
        catalog.setUpdateTime(LocalDateTime.now());
        catalog.setUpdateBy(ContextUtil.getCurrentUser().getAccount());
        return this.updateById(catalog);
    }

    @Override
    public boolean updateCategory(CategoryCreateDto createDto) {
        if (createDto.getCatalogId() == null) {
            throw new BaseException("目录节点不存在");
        }
        CostCatalog newParentCatalog = this.getById(createDto.getParentId());
        CostCatalog catalog = this.getById(createDto.getCatalogId());


        if (catalog == null) {
            throw new BaseException("目录节点不存在");
        }

        if (ObjectUtil.isNotEmpty(newParentCatalog) && ObjectUtil.isNotEmpty(catalog)) {
            String newLayerLevel = newParentCatalog.getLayerLevel() + "," + newParentCatalog.getCatalogId();
            String layerLevel = catalog.getLayerLevel();
            catalog.setLayerLevel(newLayerLevel);
            updateDeptChildren(catalog.getCatalogId(), newLayerLevel, layerLevel);
        }

        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getCode, createDto.getCode());
        queryWrapper.ne(CostCatalog::getCatalogId, createDto.getCatalogId());
        int count = this.count(queryWrapper);
        if (count > 0) {
            throw new BaseException("目录编码已存在");
        }
        catalog.setCatalogName(createDto.getCatalogName());
        catalog.setRemark(createDto.getRemark());
        catalog.setUpdateTime(LocalDateTime.now());
        catalog.setUpdateBy(ContextUtil.getCurrentUser().getAccount());
        catalog.setNodeType(createDto.getNodeType());
        return this.updateById(catalog);
    }

    @Override
    public boolean updateContent(ContentCreateDto createDto) {
        if (createDto.getCatalogId() == null) {
            throw new BaseException("目录节点不存在");
        }
        CostCatalog newParentCatalog = this.getById(createDto.getParentId());
        CostCatalog catalog = this.getById(createDto.getCatalogId());


        if (catalog == null) {
            throw new BaseException("目录节点不存在");
        }

        if (ObjectUtil.isNotEmpty(newParentCatalog) && ObjectUtil.isNotEmpty(catalog)) {
            String newLayerLevel = newParentCatalog.getLayerLevel() + "," + newParentCatalog.getCatalogId();
            String layerLevel = catalog.getLayerLevel();
            catalog.setLayerLevel(newLayerLevel);
            updateDeptChildren(catalog.getCatalogId(), newLayerLevel, layerLevel);
        }

        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getCode, createDto.getCode());
        queryWrapper.ne(CostCatalog::getCatalogId, createDto.getCatalogId());
        int count = this.count(queryWrapper);
        if (count > 0) {
            throw new BaseException("目录编码已存在");
        }
        catalog.setAuditType(createDto.getAuditType());
        catalog.setCatalogName(createDto.getCatalogName());
        catalog.setPriceLevel(createDto.getPriceLevel());
        catalog.setPricingDept(createDto.getPricingDept());
        catalog.setRemark(createDto.getRemark());
        catalog.setUpdateTime(LocalDateTime.now());
        catalog.setUpdateBy(ContextUtil.getCurrentUser().getAccount());
        catalog.setNodeType(createDto.getNodeType());
        return this.updateById(catalog);
    }


    public void updateDeptChildren(String catalogId, String newAncestors, String oldAncestors) {
        List<CostCatalog> children = this.getBaseMapper().selectChildrenById(catalogId);
        for (CostCatalog child : children) {
            child.setLayerLevel(child.getLayerLevel().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0) {
            this.getBaseMapper().updateChildren(children);
        }
    }


    @Override
    public boolean isNameDuplicate(String name, String parentId, String excludeId) {
        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getCatalogName, name);
        queryWrapper.eq(CostCatalog::getParentId, parentId);
        if (excludeId != null) {
            queryWrapper.ne(CostCatalog::getCatalogId, excludeId);
        }
        return this.count(queryWrapper) > 0;
    }

    @Override
    public String generateNewCode(String parentId) {
        // 1. 查询父节点
        CostCatalog parentCatalog = this.getById(parentId);

        // 2. 查询同级节点中按创建时间倒序排列的第一个节点（最新创建的节点）
        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getParentId, parentId);
        queryWrapper.orderByDesc(CostCatalog::getCreateTime);
        CostCatalog lastNode = this.getOne(queryWrapper, false);

        // 3. 生成新编码
        if (parentCatalog == null || "root".equals(parentCatalog.getNodeType())) {
            // 一级节点：001, 002, 003...
            int nextNum = 1;
            if (lastNode != null && lastNode.getCode() != null) {
                try {
                    nextNum = Integer.parseInt(lastNode.getCode()) + 1;
                } catch (NumberFormatException e) {
                    // 如果解析失败，默认从1开始
                    nextNum = 1;
                }
            }
            return String.format("%03d", nextNum);
        } else {
            // 二级及以下节点：001001, 001002... (父编码+三位序号)
            String parentCode = parentCatalog.getCode();
            int nextNum = 1;
            if (lastNode != null && lastNode.getCode() != null && lastNode.getCode().startsWith(parentCode)) {
                // 从最后节点编码中提取序号部分（去掉父编码前缀）
                String lastCodeSuffix = lastNode.getCode().substring(parentCode.length());
                if (!lastCodeSuffix.isEmpty()) {
                    try {
                        nextNum = Integer.parseInt(lastCodeSuffix) + 1;
                    } catch (NumberFormatException e) {
                        // 如果解析失败，默认从1开始
                        nextNum = 1;
                    }
                }
            }
            return parentCode + String.format("%03d", nextNum);
        }

    }

    @Override
    public List<CostCatalog> getCategoryList() {
        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getNodeType, BaseConstant.CATALOG_TYPE_LX);
        return this.list(queryWrapper);
    }


    //根据id删除
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeById(Serializable id) {
        CostCatalog catalog = this.getById(id);
        if (catalog == null) {
            throw new BaseException("目录不存在");
        }

        // 检查是否存在子节点
        LambdaQueryWrapper<CostCatalog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostCatalog::getIsDeleted, BaseConstant.NORMAL_STATUS);
        queryWrapper.eq(CostCatalog::getParentId, id.toString());
        int childCount = this.count(queryWrapper);

        if (childCount > 0) {
            throw new BaseException("该目录下存在子节点，无法删除");
        }
        CostCatalog updateCatalog = new CostCatalog();
        updateCatalog.setCatalogId((String) id);
        updateCatalog.setIsDeleted(BaseConstant.DELETE_FLAG);
        updateCatalog.setUpdateTime(LocalDateTime.now());
        updateCatalog.setUpdateBy(ContextUtil.getCurrentUser().getAccount());
        return this.updateById(updateCatalog);
    }

}
