package com.gci.boot.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.modules.system.entity.SysPermission;
import com.gci.boot.exception.GciBootException;
import com.gci.boot.modules.system.entity.SysRolePermission;
import com.gci.boot.modules.system.mapper.SysPermissionMapper;
import com.gci.boot.modules.system.service.ISysPermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gci.boot.modules.system.service.ISysRolePermissionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author chenzhiwei
 * @since 2023-08-18
 */
@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements ISysPermissionService {

    @Autowired
    private ISysRolePermissionService sysRolePermissionService;

    @Override
    public List<SysPermission> queryByUser(String username) {
        return this.baseMapper.queryByUser(username);
    }

    @Override
    public void addPermission(SysPermission sysPermission) throws GciBootException {
        //----------------------------------------------------------------------
        //判断是否是一级菜单，是的话清空父菜单
        if(CommonConstant.MENU_TYPE_MAIN.equals(sysPermission.getMenuType())) {
            sysPermission.setParentId(null);
        }
        //----------------------------------------------------------------------
        String pid = sysPermission.getParentId();
        if(StringUtils.isNotBlank(pid)) {
            //设置父节点不为叶子节点
            lambdaUpdate().eq(SysPermission::getId, pid).set(SysPermission::getIsLeaf, 0).update();
        }
        sysPermission.setCreateTime(new Date());
        sysPermission.setIsLeaf(1);
        this.save(sysPermission);
    }

    @Override
    public void editPermission(SysPermission sysPermission) throws GciBootException {
        SysPermission p = this.getById(sysPermission.getId());
        //TODO 该节点判断是否还有子节点
        if(p==null) {
            throw new GciBootException("未找到菜单信息");
        }else {
            sysPermission.setUpdateTime(new Date());
            //----------------------------------------------------------------------
            //Step1.判断是否是一级菜单，是的话清空父菜单ID
            if(CommonConstant.MENU_TYPE_MAIN.equals(sysPermission.getMenuType())) {
                sysPermission.setParentId("");
            }
            //Step2.判断菜单下级是否有菜单，无则设置为叶子节点
            int count = this.count(new QueryWrapper<SysPermission>().lambda().eq(SysPermission::getParentId, sysPermission.getId()));
            if(count==0) {
                sysPermission.setIsLeaf(1);
            }
            //----------------------------------------------------------------------
            this.updateById(sysPermission);

            //如果当前菜单的父菜单变了，则需要修改新父菜单和老父菜单的，叶子节点状态
            String pid = sysPermission.getParentId();
            if((StringUtils.isNotBlank(pid) && !pid.equals(p.getParentId())) || StringUtils.isBlank(pid)&&StringUtils.isNotBlank(p.getParentId())) {
                //a.设置新的父菜单不为叶子节点
                lambdaUpdate().eq(SysPermission::getId, pid).set(SysPermission::getIsLeaf, 0).update();
                //b.判断老的菜单下是否还有其他子菜单，没有的话则设置为叶子节点
                int cc = this.count(new QueryWrapper<SysPermission>().lambda().eq(SysPermission::getParentId, p.getParentId()));
                if(cc==0) {
                    if(StringUtils.isNotBlank(p.getParentId())) {
                        lambdaUpdate().eq(SysPermission::getId, p.getParentId()).set(SysPermission::getIsLeaf, 1).update();
                    }
                }

            }
        }

    }


    @Override
    @Transactional
    public void deletePermission(String id) throws GciBootException {
        SysPermission sysPermission = this.getById(id);
        if(sysPermission==null) {
            throw new GciBootException("未找到菜单信息");
        }
        String pid = sysPermission.getParentId();
        if(StringUtils.isNotBlank(pid)) {
            int count = lambdaQuery().eq(SysPermission::getParentId, pid).count();
            if(count==1) {
                //若父节点无其他子节点，则该父节点是叶子节点
                lambdaUpdate().eq(SysPermission::getId, pid).set(SysPermission::getIsLeaf, 1);
            }
        }
        baseMapper.deleteById(id);
        // 该节点可能是子节点但也可能是其它节点的父节点,所以需要级联删除
        lambdaQuery().eq(SysPermission::getParentId, sysPermission.getId()).list()
                .forEach(p -> deletePermission(p.getId()));
        //删除角色授权表
        sysRolePermissionService.lambdaUpdate().eq(SysRolePermission::getPermissionId, id).remove();
    }

    @Override
    public Set<String> getPermCodeSetByroleIds(Collection<String> roleIds){
        return baseMapper.getPermCodeSetByroleIds(roleIds);
    }
}
