package com.system.oauth.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.system.framework.core.response.StarBosResult;
import com.system.oauth.system.entity.SysPermission;
import com.system.oauth.system.entity.SysRolePermission;

import com.system.oauth.system.model.RolePermissionIdsModel;
import com.system.oauth.system.model.TreeModel;
import com.system.oauth.system.service.ISysPermissionService;
import com.system.oauth.system.service.ISysRolePermissionService;
import com.system.oauth.utils.PermissionDataUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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

import static com.system.oauth.constant.enums.PermissionTypeEnum.BUTTON_PERMISSIONS;

/**
 * @Description:
 * @Author:
 * @Date: 2022-01-10
 * @Version: V1.0
 */
@Api(tags = "菜单权限管理")
@RestController
@Slf4j
@RequestMapping("/permission")
public class SysPermissionController {

    @Autowired
    ISysPermissionService permissionService;

    @Autowired
    ISysRolePermissionService rolePermissionService;

    @GetMapping("/list")
//    @PreAuthorize("hasAuthority('getMenuTree')")
    @ApiOperation(value = "获取权限树", httpMethod = "GET", produces = "", notes = "获取权限树")
    public StarBosResult<?> list() {
        LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();

//        query.ne(SysPermission::getType, BUTTON_PERMISSIONS.getKey());
        query.orderByAsc(SysPermission::getSortNo);
        List<SysPermission> list = permissionService.list(query);
        List<SysPermission> permissions = iterateTreeList(list, null);
        return StarBosResult.ok(permissions);
    }

    @GetMapping("/getMenuTree")
//    @PreAuthorize("hasAuthority('getMenuTree')")
    @ApiOperation(value = "获取菜单路由", httpMethod = "GET", produces = "", notes = "获取菜单路由")
    public StarBosResult<?> getMenuTree() {
        LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();

        query.ne(SysPermission::getType, BUTTON_PERMISSIONS.getKey());
        query.orderByAsc(SysPermission::getSortNo);
        List<SysPermission> list = permissionService.list(query);
        List<SysPermission> permissions = iterateTreeList(list, null);
//        log.info("\r\n"+permissions);
        return StarBosResult.ok(permissions);
    }

    /**
     * 添加菜单
     *
     * @param permission
     * @return
     */
    //
    @PostMapping(value = "/add")
    @ApiOperation(value = "添加菜单", httpMethod = "POST", produces = "application/json", notes = "添加菜单")
    public StarBosResult<?> add(@RequestBody SysPermission permission) {
        StarBosResult<SysPermission> result = new StarBosResult<SysPermission>();
        try {
//            String accountId = AuthUtils.getAccountId();
//            permission.setFcreator(accountId);
            permission = PermissionDataUtil.intelligentProcessData(permission);
            permissionService.addPermission(permission);
            result.success("添加成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }
        return result;
    }


    /**
     * 编辑菜单
     *
     * @param permission
     * @return
     */
    @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
    @ApiOperation(value = "编辑菜单", httpMethod = "POST", produces = "", notes = "编辑菜单")
    public StarBosResult<?> edit(@RequestBody SysPermission permission) {
        StarBosResult<SysPermission> result = new StarBosResult<>();
        try {
            permission = PermissionDataUtil.intelligentProcessData(permission);
            permissionService.editPermission(permission);
            result.success("修改成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败 " + e.getMessage());
        }
        return result;
    }


    /**
     * 删除菜单
     *
     * @param id
     * @return
     */
    @DeleteMapping(value = "/delete")
    @ApiOperation(value = "删除菜单", httpMethod = "DELETE", produces = "", notes = "删除菜单")
    public StarBosResult<?> delete(@RequestParam(name = "id", required = true) String id) {

        StarBosResult<SysPermission> result = new StarBosResult<>();
        try {
            permissionService.deletePermission(id);
            result.success("删除成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500(e.getMessage());
        }
        return result;
    }


    /**
     * 获取全部的权限树
     *
     * @return
     */
    @ApiOperation(value = "获取全部的权限树", httpMethod = "GET", produces = "", notes = "获取全部的权限树")
    @RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
    public StarBosResult<Map<String, Object>> queryTreeList() {
        StarBosResult<Map<String, Object>> result = new StarBosResult<>();
        // 全部权限ids
        List<String> ids = new ArrayList<>();
        try {
            LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
            query.ne(SysPermission::getType, BUTTON_PERMISSIONS.getKey());
//            query.eq(Permission::getDelFlag, CommonConstant.DEL_FLAG_0);
            query.orderByAsc(SysPermission::getSortNo);
            List<SysPermission> list = permissionService.list(query);
            for (SysPermission sysPer : list) {
                ids.add(sysPer.getId().toString());
            }
            List<TreeModel> treeList = new ArrayList<>();
            getTreeModelList(treeList, list, null);
            Map<String, Object> resMap = new HashMap<String, Object>();
            resMap.put("treeList", treeList); // 全部树节点数据
            resMap.put("ids", ids);// 全部树ids
            result.setData(resMap);
            result.setCode(200);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }


    /**
     * 查询角色授权
     *
     * @return
     */
    @GetMapping(value = "/queryRolePermission")
    @ApiOperation(value = "查询角色授权", httpMethod = "GET", produces = "", notes = "查询角色授权")
    public StarBosResult<List<String>> queryRolePermission(@RequestParam(name = "id", required = true) String roleId) {
        StarBosResult<List<String>> result = new StarBosResult<>();
        try {
            List<SysRolePermission> list = rolePermissionService.list(new QueryWrapper<SysRolePermission>().lambda().eq(SysRolePermission::getRoleId, roleId));
            result.setData(list.stream().map(SysRolePermission -> String.valueOf(SysRolePermission.getPermId())).collect(Collectors.toList()));
            result.setCode(200);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 保存角色授权
     *
     * @return
     */
    @ApiOperation(value = "保存角色授权", httpMethod = "POST", produces = "", notes = "保存角色授权")
    @RequestMapping(value = "/saveRolePermission", method = RequestMethod.POST)
    @ApiImplicitParam(name = "授权参数",value = "角色id:roleId,变更后权限ids:permissionIds,变更前权限ids:lastpermissionIds。",dataType="String")
    public StarBosResult<String> saveRolePermission(@RequestBody RolePermissionIdsModel json) {
//        log.info("\r\n"+json);
        long start = System.currentTimeMillis();
        StarBosResult<String> result = new StarBosResult<>();
        try {
            String roleId = json.getRoleId();
            List<String> permissionIds = json.getPermissionIds();
            List<String> lastPermissionIds = json.getLastPermissionIds();
            this.rolePermissionService.saveRolePermission(roleId, permissionIds, lastPermissionIds);
            result.success("保存成功！");
            log.info("======角色授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒");
        } catch (Exception e) {
            result.error500("授权失败！");
            log.error(e.getMessage(), e);
        }
        return result;
    }


    private void getTreeModelList(List<TreeModel> treeList, List<SysPermission> metaList, TreeModel temp) {
        for (SysPermission permission : metaList) {
            String tempPid = permission.getParentId().toString();
            TreeModel tree = new TreeModel(permission);
            if (temp == null && "0".equals(tempPid)) {
                treeList.add(tree);
                if (!tree.getIsLeaf()) {
                    getTreeModelList(treeList, metaList, tree);
                }
            } else if (temp != null && tempPid != "0" && tempPid.equals(temp.getKey())) {
                temp.getChildren().add(tree);
                if (!tree.getIsLeaf()) {
                    getTreeModelList(treeList, metaList, tree);
                }
            }

        }
    }


    /**
     * 多级菜单查询方法
     *
     * @param menuVoList 不包含最高层次菜单的菜单集合
     * @param pid        父类id
     * @return
     */
    public List<SysPermission> iterateTreeList(List<SysPermission> menuVoList, String pid) {
        List<SysPermission> result = new ArrayList<SysPermission>();
        if (pid == null) {
            for (SysPermission menu : menuVoList) {
                if (menu.getParentId().equals("0")) {
                    List<SysPermission> menus = iterateTreeList(menuVoList, menu.getId().toString());
                    menu.setChildren(menus);
                    result.add(menu);
                }
            }
        } else if (pid != null) {
            for (SysPermission menu : menuVoList) {
                //获取菜单的id
                String menuid = menu.getId().toString();
                //获取菜单的父id
                String parentid = menu.getParentId().toString();
                if (StringUtils.isNotBlank(parentid)) {
                    if (parentid.equals(pid)) {
                        //递归查询当前子菜单的子菜单
                        List<SysPermission> iterateMenu = iterateTreeList(menuVoList, menuid);
                        menu.setChildren(iterateMenu);
                        result.add(menu);
                    }
                }
            }
        }

        return result;
    }

}
