package jnpf.cultivate.v2.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.cultivate.mapper.FtbCultivateIdentifyCategoriesMapper;
import jnpf.cultivate.mapper.FtbCultivateIdentifyItemsPoolMapper;
import jnpf.cultivate.v2.service.FtbCultivateIdentifyCategoriesService;
import jnpf.enums.cultivate.CultivateIsSystemEnum;
import jnpf.model.cultivate.dto.learn.BatchCommonCountDto;
import jnpf.model.cultivate.po.FtbCultivateIdentifyCategories;
import jnpf.model.cultivate.po.FtbCultivateIdentifyItemsPool;
import jnpf.model.cultivate.v2.identify.req.QueryIdentifyCategoryListReq;
import jnpf.model.cultivate.v2.identify.req.V2SaveItemCategoryReq;
import jnpf.model.cultivate.v2.identify.vo.V2IdentifyCategoryTreeVo;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 鉴定项分类服务实现类
 *
 * @author lingma
 * @since 2026-02-24
 */
@Slf4j
@Service
public class FtbCultivateIdentifyCategoriesServiceImpl extends ServiceImpl<FtbCultivateIdentifyCategoriesMapper, FtbCultivateIdentifyCategories> implements FtbCultivateIdentifyCategoriesService {


    @Autowired
    private FtbCultivateIdentifyItemsPoolMapper ftbCultivateIdentifyItemsPoolMapper;


    /**
     * 分类树
     *
     * @param req 查询参数
     * @return 分类树
     */
    @Override
    public List<V2IdentifyCategoryTreeVo> getCategoryTree(QueryIdentifyCategoryListReq req) {
        List<FtbCultivateIdentifyCategories> categories = this.list(new LambdaQueryWrapper<FtbCultivateIdentifyCategories>().eq(FtbCultivateIdentifyCategories::getEnabledMark, 0).like(StringUtils.isNotBlank(req.getKeyWord()), FtbCultivateIdentifyCategories::getName, req.getKeyWord()).orderByAsc(FtbCultivateIdentifyCategories::getCreatorTime));

        if (CollUtil.isEmpty(categories)) {
            return new ArrayList<>();
        }
        List<String> ids = new ArrayList<>();
        for (FtbCultivateIdentifyCategories category : categories) {
            ids.add(category.getId());
            if (!"0".equals(category.getParentId())) {
                ids.add(category.getParentId());
            }
        }
        List<FtbCultivateIdentifyCategories> allLists = this.listByIds(ids);
        List<V2IdentifyCategoryTreeVo> list = allLists.stream().map(this::convertToVo).collect(Collectors.toList());
        //查询分类的数量

        List<BatchCommonCountDto> groupedResult = ftbCultivateIdentifyItemsPoolMapper.countByCateId();
        Map<String, Integer> countMap = new HashMap<>();
        if (CollUtil.isNotEmpty(groupedResult)) {
            countMap = groupedResult.stream().collect(Collectors.toMap(BatchCommonCountDto::getSelectKey, BatchCommonCountDto::getNum));
        }
        return buildCateTree(list, countMap);

    }

    /**
     * 新增分类
     *
     * @param req 新增参数
     * @return 分类
     */
    @Override
    public FtbCultivateIdentifyCategories insertData(V2SaveItemCategoryReq req) {
        String userId = UserProvider.getUser().getUserId();
        //检测名称是否重复
        QueryWrapper<FtbCultivateIdentifyCategories> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbCultivateIdentifyCategories::getName, req.getName())
                .eq(FtbCultivateIdentifyCategories::getEnabledMark, 0);
        Long count = baseMapper.selectCount(wrapper);
        if (null != count && count > 0) {
            throw new RuntimeException("名称已经存在");
        }
        FtbCultivateIdentifyCategories entity = new FtbCultivateIdentifyCategories();
        entity.setName(req.getName());
        if (StringUtils.isEmpty(req.getParentId())) {
            entity.setParentId("0");
        } else {
            entity.setParentId(req.getParentId());
        }
        entity.setEnabledMark(0);
        entity.setLastModifyUserId(userId);
        entity.setCreatorUserId(userId);
        entity.setCreatorTime(new java.util.Date());
        entity.setLastModifyTime(new java.util.Date());
        entity.setIsSystem(CultivateIsSystemEnum.NO.getCode());

        baseMapper.insert(entity);
        return entity;
    }

    /**
     * 修改分类
     *
     * @param id  分类id
     * @param req 修改参数
     * @return 分类
     */
    @Override
    public FtbCultivateIdentifyCategories updateData(String id, V2SaveItemCategoryReq req) {
        queryAndCheckById(id);
        //检测名称是否重复
        QueryWrapper<FtbCultivateIdentifyCategories> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbCultivateIdentifyCategories::getName, req.getName())
                .ne(FtbCultivateIdentifyCategories::getId, id)
                .eq(FtbCultivateIdentifyCategories::getEnabledMark, 0);
        Long count = baseMapper.selectCount(wrapper);
        if (null != count && count > 0) {
            throw new RuntimeException("分类名称已经存在");
        }
        if(StringUtils.isEmpty(req.getParentId())){
            req.setParentId("0");
        }
        if (StringUtils.isNotEmpty(req.getParentId()) && !"0".equals(req.getParentId())) {
            queryAndCheckParent(req.getParentId());
        }
        if(id.equals(req.getParentId())){
            throw new RuntimeException("上级分类不能是自己");
        }
        String userId = UserProvider.getUser().getUserId();
        //修改分类
        FtbCultivateIdentifyCategories categories = new FtbCultivateIdentifyCategories();
        categories.setName(req.getName());
        categories.setId(id);
        categories.setEnabledMark(0);
        categories.setLastModifyUserId(userId);
        categories.setLastModifyTime(new java.util.Date());
        categories.setParentId(req.getParentId());
        baseMapper.updateById(categories);
        return categories;
    }

    /**
     * 删除分类
     *
     * @param id 分类id
     */
    @Override
    public void deleteData(String id) {

        //检测分类是否删除
        FtbCultivateIdentifyCategories identifyCategories = queryAndCheckById(id);
        if(identifyCategories.getIsSystem().equals(CultivateIsSystemEnum.YES.getCode())){
            throw new RuntimeException("系统内置分类不能删除");
        }

        //检测分类下是否有下级分类
        List<String> childCategoryIds = queryChildCategoryIds(id);
        if (CollUtil.isNotEmpty(childCategoryIds)) {
            throw new RuntimeException("请先删除该分类下的所有子分类");
        }
        long count = ftbCultivateIdentifyItemsPoolMapper.selectCount(new LambdaQueryWrapper<FtbCultivateIdentifyItemsPool>().eq(FtbCultivateIdentifyItemsPool::getCateId, id).eq(FtbCultivateIdentifyItemsPool::getEnabledMark, 0));
        if (count > 0) {
            throw new RuntimeException("请先删除该分类下的鉴定项");
        }

        baseMapper.update(null, new LambdaUpdateWrapper<FtbCultivateIdentifyCategories>()
                .eq(FtbCultivateIdentifyCategories::getId, id)
                .set(FtbCultivateIdentifyCategories::getEnabledMark, 1));
    }

    @Override
    public List<String> getAllNameList() {
        List<FtbCultivateIdentifyCategories> categoriesList = getAllList();
        List<String> nameList = new ArrayList<>();
        if (CollUtil.isNotEmpty(categoriesList)) {
            for (FtbCultivateIdentifyCategories ftbNoticeCategories : categoriesList) {
                nameList.add(ftbNoticeCategories.getName());
            }
        }
        return nameList;
    }

    @Override
    public List<FtbCultivateIdentifyCategories> getAllList() {
        QueryWrapper<FtbCultivateIdentifyCategories> wrapper = new QueryWrapper<>();
        wrapper.lambda().ne(FtbCultivateIdentifyCategories::getParentId, '0')
                .eq(FtbCultivateIdentifyCategories::getEnabledMark, 0);
        return baseMapper.selectList(wrapper);

    }

    public List<String> queryChildCategoryIds(String id) {

        QueryWrapper<FtbCultivateIdentifyCategories> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(FtbCultivateIdentifyCategories::getParentId, id).eq(FtbCultivateIdentifyCategories::getEnabledMark, 0);
        List<FtbCultivateIdentifyCategories> categoriesList = baseMapper.selectList(wrapper);
        List<String> childIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(categoriesList)) {
            for (FtbCultivateIdentifyCategories ftbNoticeCategories : categoriesList) {
                childIds.add(ftbNoticeCategories.getId());
            }
        }
        return childIds;
    }


    private void queryAndCheckParent(String parentId) {
        FtbCultivateIdentifyCategories parent = baseMapper.selectById(parentId);
        if (null == parent) {
            throw new RuntimeException("父级分类不存在");
        }
        if (parent.getEnabledMark().equals(1)) {
            throw new RuntimeException("父级分类已被删除");
        }
        if(StringUtils.isNotEmpty(parent.getParentId()) && !"0".equals(parent.getParentId())){
            throw new RuntimeException("父级分类不能有父级分类");
        }
    }

    public FtbCultivateIdentifyCategories queryAndCheckById(String id) {
        FtbCultivateIdentifyCategories entity = baseMapper.selectById(id);
        if (null == entity) {
            throw new RuntimeException("分类不存在");
        }
        if (entity.getEnabledMark().equals(1)) {
            throw new RuntimeException("分类已经删除");
        }
        return entity;
    }


    private List<V2IdentifyCategoryTreeVo> buildCateTree(List<V2IdentifyCategoryTreeVo> list, Map<String, Integer> countMap) {
        List<V2IdentifyCategoryTreeVo> retList = new ArrayList<>();
        Map<String, List<V2IdentifyCategoryTreeVo>> map = new HashMap<>();
        for (V2IdentifyCategoryTreeVo dto : list) {
            Integer count = countMap.get(dto.getId());
            dto.setCount(Objects.requireNonNullElse(count, 0));
            if ("0".equals(dto.getParentId())) {
                retList.add(dto);
            } else {
                List<V2IdentifyCategoryTreeVo> tempList = map.get(dto.getParentId());
                if (CollUtil.isEmpty(tempList)) {
                    tempList = new ArrayList<>();
                }
                tempList.add(dto);
                map.put(dto.getParentId(), tempList);
            }
        }

        for (V2IdentifyCategoryTreeVo dto : list) {
            List<V2IdentifyCategoryTreeVo> child = map.get(dto.getId());
            if (CollUtil.isNotEmpty(child)) {
                dto.setChildren(child);
            }
        }
        return retList;
    }


    /**
     * 转换为VO对象
     *
     * @param category 分类实体
     * @return VO对象
     */
    private V2IdentifyCategoryTreeVo convertToVo(FtbCultivateIdentifyCategories category) {
        V2IdentifyCategoryTreeVo vo = new V2IdentifyCategoryTreeVo();
        BeanUtil.copyProperties(category, vo);
        return vo;
    }
}