package cn.iocoder.yudao.module.system.service.nursing;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.NursingCategoryDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.NursingCategoryMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;


@Service
public class NursingCategoryServiceImpl implements NursingCategoryService {

    @Resource
    private NursingCategoryMapper categoryMapper;


    @Override
    public void add(NursingCategoryDO category) {
        if (category.getParentId() == null) {
            category.setParentId(0L); //一级分类
        }
        category.setTenantId(category.getTenantId() == null ? TenantContextHolder.getTenantId() : category.getTenantId());
        category.setCreateTime(new Date());
        categoryMapper.insert(category);
    }

    @Override
    public void edit(NursingCategoryDO category) {
        if (category.getParentId() != null) {
            if (category.getId().intValue() == category.getParentId().intValue()) {
                throw exception(NURSE_CATEGORY_IS_USED);
            }
        }
        if (category.getParentId() == null) {
            category.setParentId(0L);  //未传父类ID 当一级分类
        }
        categoryMapper.updateById(category);
    }

    @Override
    public NursingCategoryDO getDetailById(Long id) {
        return categoryMapper.selectById(id);
    }

    @Override
    public void delete(Long id) {
        List<NursingCategoryDO> list = categoryMapper.selectList(new LambdaQueryWrapperX<NursingCategoryDO>().eq(NursingCategoryDO::getParentId, id));
        if (CollectionUtil.isNotEmpty(list)) {
            throw exception(HAS_CHILDREN_NODE);
        }
        categoryMapper.deleteById(id);
    }

    @Override
    public List<NursingCategoryDO> getTree(Long[] tenantIds, Integer orgType) {
        List<NursingCategoryDO> parentList = categoryMapper.selectList(new LambdaQueryWrapperX<NursingCategoryDO>()
                .eq(NursingCategoryDO::getParentId, 0)
                .inIfPresent(NursingCategoryDO::getTenantId,tenantIds)
                .eqIfPresent(NursingCategoryDO::getOrgType,orgType));
        List<NursingCategoryDO> dataList = parentList.stream().map(item -> this.getTreeById(item.getId())).collect(Collectors.toList());
        return dataList;
    }


    public NursingCategoryDO getTreeById(Long id) {
        NursingCategoryDO category = categoryMapper.selectById(id);
        List<NursingCategoryDO> list = categoryMapper.selectList(null);
        category.setChildrenList(getAllSubNodes(category, list));
        return category;
    }

    private List<NursingCategoryDO> getAllSubNodes(NursingCategoryDO rootNode, List<NursingCategoryDO> list) {
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        return list.stream().filter(item -> item.getParentId().equals(rootNode.getId())).peek(menu -> menu.setChildrenList(getAllSubNodes(menu, list)))
                .collect(Collectors.toList());
    }

    /**
     * 根据父类ID查询下面所有子类的ID集合
     *
     * @param id
     * @return
     */

    @Override
    public List<Long> getIdListByParent(Long id) {
        List<Long> ids = new ArrayList<>();
        NursingCategoryDO parentNode = getTreeById(id);
        dfs(parentNode, ids);
        return ids;
    }


    private void dfs(NursingCategoryDO node, List<Long> ids) {
        if (node == null) {
            return;
        }
        ids.add(node.getId()); // 将当前节点的ID添加到集合中
        for (NursingCategoryDO child : node.getChildrenList()) {
            dfs(child, ids); // 递归遍历子节点
        }
    }

}
