package com.ytpm.middle.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageInfo;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.general.ResultTable;
import com.ytpm.handle.CustomerException;
import com.ytpm.middle.dao.PermissionMapper;
import com.ytpm.middle.enums.PermissionTypeEnum;
import com.ytpm.middle.model.YtMiddlePermission;
import com.ytpm.middle.param.MiddlePermissionParam;
import com.ytpm.middle.service.PermissionService;
import com.ytpm.middle.view.DropDownVO;
import com.ytpm.middle.view.MiddlePermissionVO;
import com.ytpm.middle.view.MiddleRoleVO;
import com.ytpm.middle.view.MiddleUserInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
public class PermissionServiceImpl implements PermissionService {

    @Resource
    private PermissionMapper permissionMapper;

    /**
     * 查询权限列表
     */
    @Override
    public ResultTable<MiddlePermissionVO> queryTree(MiddlePermissionParam param) {
        List<MiddlePermissionVO> allList = permissionMapper.queryAll(param);
        if(CollUtil.isEmpty(allList)){
            return ResultTable.resultTableOk(new PageInfo<>(Collections.emptyList()));
        }
        //过滤一级列表
        List<MiddlePermissionVO> firstList = allList.stream().filter(
                s-> Objects.isNull(s.getParentId())).collect(Collectors.toList());
        //递归处理菜单设置子列表
        for (MiddlePermissionVO vo : firstList) {
            recursionChildPermission(vo,allList);
        }
        return ResultTable.resultTableOk(new PageInfo<>(firstList));
    }

    /**
     * 新增权限
     */
    @Override
    public Result<String> addOne(MiddlePermissionParam param) {
        YtMiddlePermission permission;
        if(PermissionTypeEnum.MENU.getCode().equals(param.getType())){
            permission = permissionMapper.getByRoute(param.getRoute());
        }else{
            permission = permissionMapper.getByCode(param.getPermissionCode());
        }
        if(Objects.nonNull(permission)){
            return Result.resultErr(RepMessage.OBJECT_ALREADY_EXIST);
        }
        YtMiddlePermission middlePermission = new YtMiddlePermission();
        BeanUtils.copyProperties(param,middlePermission);
        permissionMapper.insertOne(middlePermission);
        return Result.resultOk(RepMessage.SAVE_SUCCESS);
    }

    /**
     * 修改权限
     */
    @Override
    public Result<String> updateOne(MiddlePermissionParam param) {
        YtMiddlePermission permission;
        if(PermissionTypeEnum.MENU.getCode().equals(param.getType())){
            permission = permissionMapper.getByRoute(param.getRoute());
        }else{
            permission = permissionMapper.getByCode(param.getPermissionCode());
        }
        if(Objects.isNull(permission)){
            return Result.resultErr(RepMessage.OBJECT_NOT_EXIST);
        }
        YtMiddlePermission middlePermission = new YtMiddlePermission();
        BeanUtils.copyProperties(param,middlePermission);
        permissionMapper.updateById(middlePermission);
        return Result.resultOk(RepMessage.MODIFY_SUCCESS);
    }

    /**
     * 删除权限ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> delOne(int permissionId, String userId) {
        YtMiddlePermission permission = permissionMapper.selectPrimary(permissionId);
        if(Objects.isNull(permission)){
            return Result.resultErr(RepMessage.OBJECT_NOT_EXIST);
        }
        YtMiddlePermission middlePermission = new YtMiddlePermission();
        middlePermission.setPermissionId(permissionId);
        middlePermission.setAvailable(0);
        middlePermission.setUpdateParam(userId);
        permissionMapper.updateById(middlePermission);
        permissionMapper.delByParentId(permissionId,userId);
        return Result.resultOk(RepMessage.DELETE_SUCCESS);
    }

    /**
     * 查询权限下拉列表
     */
    @Override
    public ResultTable<DropDownVO> permissionDropList() {
        return ResultTable.resultTableOk(new PageInfo<>(permissionMapper.permissionDropList()));
    }

    /**
     * 根据用户信息查询菜单
     */
    @Override
    public ResultTable<MiddlePermissionVO> getMenuByRole(MiddleUserInfo userInfo) {
        List<MiddlePermissionVO> menuList;
        if(1==userInfo.getSuperAdmin()){
            menuList = permissionMapper.selectByType(PermissionTypeEnum.MENU.getCode());
        }else{ //普通用户
            List<MiddleRoleVO> roleList = userInfo.getRoleList();
            if(CollUtil.isEmpty(roleList)){
                return ResultTable.resultTableOk(new PageInfo<>(Collections.emptyList()));
            }
            List<Integer> roleIdList = roleList.stream()
                    .map(MiddleRoleVO::getRoleId).distinct().collect(Collectors.toList());
            menuList = permissionMapper.getFirstMenuByRoleIds(roleIdList);
        }
        List<MiddlePermissionVO> firstMenu = menuList.stream().filter(
                s -> Objects.isNull(s.getParentId())).collect(Collectors.toList());
        //递归处理菜单设置子列表
        for (MiddlePermissionVO menu : firstMenu) {
            recursionChildPermission(menu,menuList);
        }
        return ResultTable.resultTableOk(new PageInfo<>(firstMenu));
    }

    /**
     * 根据菜单获取权限列表
     */
    @Override
    public ResultTable<MiddlePermissionVO> getPermissionByMenu(Integer permissionId, MiddleUserInfo userInfo) {
        String roleIds = "";
        if(1 !=userInfo.getSuperAdmin()){
            List<MiddleRoleVO> roleList = userInfo.getRoleList();
            if(CollUtil.isEmpty(roleList)){
                return ResultTable.resultTableOk(new PageInfo<>(Collections.emptyList()));
            }
            roleIds = roleList.stream()
                    .map(s->String.valueOf(s.getRoleId())).collect(Collectors.joining(","));
        }
        return ResultTable.resultTableOk(new PageInfo<>(permissionMapper.getByParentId(permissionId,roleIds)));
    }

    /**
     * 根据角色查询权限列表
     */
    @Override
    public ResultTable<MiddlePermissionVO> queryTreeByRole(Integer roleId) {
        List<MiddlePermissionVO> all = permissionMapper.queryAll(new MiddlePermissionParam());
        List<MiddlePermissionVO> permissionVOS = permissionMapper.queryAllByRole(roleId);
        //过滤一级列表
        List<MiddlePermissionVO> firstList = all.stream().filter(
                s-> Objects.isNull(s.getParentId())).collect(Collectors.toList());
        //递归处理菜单设置子列表
        for (MiddlePermissionVO vo : firstList) {
            if(CollUtil.isEmpty(permissionVOS)){
                recursionChildPermission(vo,all);
            }else{
                List<Integer> permissionIdList = permissionVOS.stream().map(MiddlePermissionVO::getPermissionId)
                        .distinct().collect(Collectors.toList());
                vo.setChecked(permissionIdList.contains(vo.getPermissionId()));
                recursionChildPermission(vo,all,permissionIdList);
            }

        }
        return ResultTable.resultTableOk(new PageInfo<>(firstList));
    }

    /**
     * 递归处理菜单设置子列表
     */
    private void recursionChildPermission(MiddlePermissionVO vo, List<MiddlePermissionVO> allList) {
        List<MiddlePermissionVO> children = allList.stream()
                .filter(s -> Objects.equals(vo.getPermissionId(), s.getParentId()))
                .collect(Collectors.toList());
        if(CollUtil.isEmpty(children))return;
        vo.setChildren(children);
        for (MiddlePermissionVO child : children) {
            recursionChildPermission(child,allList);
        }
    }

    /**
     * 递归处理菜单设置子列表,并设置选中状态
     */
    private void recursionChildPermission(MiddlePermissionVO vo, List<MiddlePermissionVO> allList, List<Integer> idList) {
        List<MiddlePermissionVO> children = allList.stream()
                .filter(s -> Objects.equals(vo.getPermissionId(), s.getParentId()))
                .collect(Collectors.toList());
        if(CollUtil.isEmpty(children))return;
        vo.setChecked(idList.contains(vo.getPermissionId()));
        vo.setChildren(children);
        for (MiddlePermissionVO child : children) {
            child.setChecked(idList.contains(child.getPermissionId()));
            recursionChildPermission(child,allList,idList);
        }
    }
}
