package com.fjhx.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.base.BaseEntity;
import com.fjhx.entity.Classify;
import com.fjhx.entity.Material;
import com.fjhx.entity.Product;
import com.fjhx.enums.ClassifyTypeEnum;
import com.fjhx.mapper.ClassifyMapper;
import com.fjhx.service.ClassifyService;
import com.fjhx.service.MaterialService;
import com.fjhx.service.ProductService;
import com.fjhx.utils.Assert;
import com.fjhx.utils.TreeUtil;
import org.springblade.core.secure.utils.AuthUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 分类 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-07-06
 */
@Service
public class ClassifyServiceImpl extends ServiceImpl<ClassifyMapper, Classify> implements ClassifyService {

    @Autowired
    private ProductService productService;

    @Autowired
    private MaterialService materialService;

    @Override
    public List<JSONObject> getTree(Map<String, String> condition) {

        String type = condition.get("type");
        Assert.notEmpty(type, "分类类型不能为空");

        // 分类名称
        String name = condition.get("name");

        List<Classify> list = lambdaQuery()
                .select(Classify::getId, Classify::getName, Classify::getParentId)
                .eq(Classify::getType, type)
                .like(ObjectUtil.isNotEmpty(name), Classify::getName, name)
                .list();

        // 构建树形
        return TreeUtil.buildTree("name", list);
    }

    @Override
    public void add(Classify classify) {

        Assert.notEmpty(classify.getType(), "分类类型不能为空");
        Assert.notEmpty(classify.getName(), "分类名称不能为空");

        Long parentId = classify.getParentId();
        if (parentId == null) {
            classify.setParentId(0L);
            classify.setParentIdSet(null);
        } else if (parentId == 0L) {
            classify.setParentIdSet(null);
        } else {
            // 查询父级分类
            Classify parentClassify = getById(parentId);
            Assert.notEmpty(parentClassify, "没有找到父级分类");

            // 赋值父级id集合
            String parentIdSet = parentClassify.getParentIdSet();
            classify.setParentIdSet(
                    (ObjectUtil.isEmpty(parentIdSet) ? "" : parentIdSet + ",") + parentId);
        }

        peerNameOnly(classify.getParentId(), classify.getName(), null);
        save(classify);
    }

    @Override
    public void edit(Classify classify) {
        Assert.notEmpty(classify.getId(), "分类Id不能为空");
        Assert.notEmpty(classify.getParentId(), "父分类id不能为空");
        Assert.notEmpty(classify.getName(), "分类名称不能为空");

        peerNameOnly(classify.getParentId(), classify.getName(), classify.getId());
        updateById(classify);
    }

    @Override
    public void delete(Classify classify) {
        Long id = classify.getId();
        Integer type = classify.getType();

        Assert.notEmpty(id, "分类id不能为空");
        Assert.notEmpty(type, "分类类型不能为空");

        Long childrenCount = lambdaQuery().eq(Classify::getParentId, id).count();
        Assert.eqZero(childrenCount, "该分类下存在子级分类，无法删除");

        if (type.equals(ClassifyTypeEnum.PRODUCT_TYPE.getCode())) {
            Long relationCount = productService.lambdaQuery().eq(Product::getClassifyId, id).count();
            Assert.eqZero(relationCount, "该分类下存在产品，无法删除");
        } else {
            Long relationCount = materialService.lambdaQuery().eq(Material::getClassifyId, id).count();
            Assert.eqZero(relationCount, "该分类下存在物料，无法删除");
        }

        removeById(classify.getId());
    }

    @Override
    public List<Long> getChildrenIdList(Long classifyId) {

        Assert.isAaaignId(classifyId, "分类id错误");

        List<Classify> list = lambdaQuery()
                .select(BaseEntity::getId)
                .eq(BaseEntity::getTenantId, AuthUtil.getTenantId())
                .like(Classify::getParentIdSet, classifyId)
                .list();

        List<Long> result = list.stream().map(BaseEntity::getId).collect(Collectors.toList());

        result.add(0, classifyId);

        return result;
    }

    /**
     * 保证同级名称不重复
     */
    private void peerNameOnly(Long parentId, String classifyName, Long excludeId) {

        Long count = lambdaQuery()
                .eq(BaseEntity::getTenantId, AuthUtil.getTenantId())
                .eq(Classify::getParentId, parentId)
                .eq(Classify::getName, classifyName)
                .ne(ObjectUtil.isNotEmpty(excludeId), BaseEntity::getId, excludeId)
                .count();

        Assert.eqZero(count, "存在相同分类名称");

    }

}
