package com.ruoyi.ss.articleClassify.service.impl;

import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.TreeSelect;
import com.ruoyi.common.core.domain.entity.ArticleClassify;
import com.ruoyi.ss.articleClassify.mapper.ArticleClassifyMapper;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.ss.articleClassify.service.IArticleClassifyService;
import org.springframework.stereotype.Service;

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

/**
 * 分类管理 服务实现
 *
 * @author ruoyi
 */
@Service
public class ArticleClassifyServiceImpl implements IArticleClassifyService
{
    @Resource
    private ArticleClassifyMapper articleClassifyMapper;

    /**
     * 查询分类管理数据
     *
     * @param classify 分类信息
     * @return 分类信息集合
     */
    @Override
//    @DataScope(agentAlias = "a")
    public List<ArticleClassify> selectClassifyListWithIsolate(ArticleClassify classify)
    {
        return articleClassifyMapper.selectClassifyList(classify);
    }

    /**
     * 查询分类管理数据
     *
     * @param classify 分类信息
     * @return 分类信息集合
     */
    @Override
    public List<ArticleClassify> selectClassifyList(ArticleClassify classify)
    {
        return articleClassifyMapper.selectClassifyList(classify);
    }

    /**
     * 查询分类树结构信息
     *
     * @param classify 分类信息
     * @return 分类树信息集合
     */
    @Override
//    @DataScope(agentAlias = "a")
    public List<TreeSelect> selectClassifyTreeList(ArticleClassify classify)
    {
        List<ArticleClassify> depts = selectClassifyListWithIsolate(classify);
        return buildClassifyTreeSelect(depts);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param depts 分类列表
     * @return 树结构列表
     */
    @Override
    public List<ArticleClassify> buildClassifyTree(List<ArticleClassify> depts)
    {
        List<ArticleClassify> returnList = new ArrayList<ArticleClassify>();
        List<Long> tempList = depts.stream().map(ArticleClassify::getClassifyId).collect(Collectors.toList());
        for (ArticleClassify dept : depts)
        {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId()))
            {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = depts;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param depts 分类列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildClassifyTreeSelect(List<ArticleClassify> depts)
    {
        List<ArticleClassify> deptTrees = buildClassifyTree(depts);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 根据分类ID查询信息
     *
     * @param deptId 分类ID
     * @return 分类信息
     */
    @Override
    public ArticleClassify selectClassifyById(Long deptId)
    {
        return articleClassifyMapper.selectClassifyById(deptId);
    }

    /**
     * 根据ID查询所有子分类（正常状态）
     *
     * @param deptId 分类ID
     * @return 子分类数
     */
    @Override
    public int selectNormalChildrenClassifyById(Long deptId)
    {
        return articleClassifyMapper.selectNormalChildrenClassifyById(deptId);
    }

    /**
     * 是否存在子节点
     *
     * @param deptId 分类ID
     * @return 结果
     */
    @Override
    public boolean hasChildByclassifyId(Long deptId)
    {
        int result = articleClassifyMapper.hasChildByClassifyId(deptId);
        return result > 0;
    }

    /**
     * 查询分类是否存在用户
     *
     * @param deptId 分类ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkClassifyExistArticle(Long deptId)
    {
        int result = articleClassifyMapper.checkClassifyExistArticle(deptId);
        return result > 0;
    }

    /**
     * 校验分类名称是否唯一
     *
     * @param dept 分类信息
     * @return 结果
     */
    @Override
    public boolean checkClassifyNameUnique(ArticleClassify dept)
    {
        Long deptId = StringUtils.isNull(dept.getClassifyId()) ? -1L : dept.getClassifyId();
        ArticleClassify info = articleClassifyMapper.checkClassifyNameUnique(dept.getClassifyName(), dept.getParentId());
        if (StringUtils.isNotNull(info) && info.getClassifyId().longValue() != deptId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验分类是否有数据权限
     *
     * @param deptId 分类id
     */
    @Override
    public void checkClassifyDataScope(Long deptId)
    {
        if (!User.isAdmin(SecurityUtils.getUserId()))
        {
            ArticleClassify dept = new ArticleClassify();
            dept.setClassifyId(deptId);
            List<ArticleClassify> depts = SpringUtils.getAopProxy(this).selectClassifyListWithIsolate(dept);
            if (StringUtils.isEmpty(depts))
            {
                throw new ServiceException("没有权限访问分类数据！");
            }
        }
    }

    /**
     * 新增保存分类信息
     *
     * @param dept 分类信息
     * @return 结果
     */
    @Override
    public int insertClassify(ArticleClassify dept)
    {
        if(dept.getDeptId() == null){
            User currentUser = SecurityUtils.getLoginUser().getUser();//获取当前系统用户
            if(!currentUser.isAdmin()){
                dept.setDeptId(currentUser.getDeptId());
            }
        }
        if(dept.getParentId() != 0){
            ArticleClassify info = articleClassifyMapper.selectClassifyById(dept.getParentId());
            // 如果父节点不为正常状态,则不允许新增子节点
            if (!UserConstants.DEPT_NORMAL.equals(info.getStatus()))
            {
                throw new ServiceException("分类停用，不允许新增");
            }
            dept.setAncestors(info.getAncestors() + "," + dept.getParentId());
        }else{
            dept.setAncestors("0");
        }
        return articleClassifyMapper.insertClassify(dept);
    }

    /**
     * 修改保存分类信息
     *
     * @param dept 分类信息
     * @return 结果
     */
    @Override
    public int updateClassify(ArticleClassify dept)
    {
        ArticleClassify newParentDept = articleClassifyMapper.selectClassifyById(dept.getParentId());
        ArticleClassify oldDept = articleClassifyMapper.selectClassifyById(dept.getClassifyId());
        if (StringUtils.isNotNull(newParentDept) && StringUtils.isNotNull(oldDept))
        {
            String newAncestors = newParentDept.getAncestors() + "," + newParentDept.getClassifyId();
            String oldAncestors = oldDept.getAncestors();
            dept.setAncestors(newAncestors);
            updateDeptChildren(dept.getClassifyId(), newAncestors, oldAncestors);
        }
        int result = articleClassifyMapper.updateClassify(dept);
        if (UserConstants.DEPT_NORMAL.equals(dept.getStatus()) && StringUtils.isNotEmpty(dept.getAncestors())
                && !StringUtils.equals("0", dept.getAncestors()))
        {
            // 如果该分类是启用状态，则启用该分类的所有上级分类
            updateParentDeptStatusNormal(dept);
        }
        return result;
    }

    /**
     * 修改该分类的父级分类状态
     *
     * @param dept 当前分类
     */
    private void updateParentDeptStatusNormal(ArticleClassify dept)
    {
        String ancestors = dept.getAncestors();
        Long[] deptIds = Convert.toLongArray(ancestors);
        articleClassifyMapper.updateClassifyStatusNormal(deptIds);
    }

    /**
     * 修改子元素关系
     *
     * @param deptId 被修改的分类ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeptChildren(Long deptId, String newAncestors, String oldAncestors)
    {
        List<ArticleClassify> children = articleClassifyMapper.selectChildrenClassifyById(deptId);
        for (ArticleClassify child : children)
        {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            articleClassifyMapper.updateClassifyChildren(children);
        }
    }

    /**
     * 删除分类管理信息
     *
     * @param deptId 分类ID
     * @return 结果
     */
    @Override
    public int deleteClassifyById(Long deptId)
    {
        return articleClassifyMapper.deleteClassifyById(deptId);
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<ArticleClassify> list, ArticleClassify t)
    {
        // 得到子节点列表
        List<ArticleClassify> childList = getChildList(list, t);
        t.setChildren(childList);
        for (ArticleClassify tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<ArticleClassify> getChildList(List<ArticleClassify> list, ArticleClassify t)
    {
        List<ArticleClassify> tlist = new ArrayList<>();
        Iterator<ArticleClassify> it = list.iterator();
        while (it.hasNext())
        {
            ArticleClassify n = (ArticleClassify) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getClassifyId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<ArticleClassify> list, ArticleClassify t)
    {
        return getChildList(list, t).size() > 0;
    }
}
