package com.gci.boot.modules.system.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gci.boot.common.log.annotation.AddSysLog;
import com.gci.boot.common.util.ParamsCheckUtil;
import com.gci.boot.common.util.QueryWrapperUtil;
import com.gci.boot.common.vo.Result;
import com.gci.boot.constant.CommonConstant;
import com.gci.boot.modules.system.entity.SysPermission;
import com.gci.boot.modules.system.entity.SysRole;
import com.gci.boot.modules.system.entity.SysUserRole;
import com.gci.boot.modules.system.service.ISysPermissionService;
import com.gci.boot.modules.system.service.ISysRoleService;
import com.gci.boot.modules.system.service.ISysUserRoleService;
import com.gci.boot.modules.system.vo.TreeModel;
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.*;

/**
 * <p>
 * 角色表 前端控制器
 * </p>
 *
 * @author chenzhiwei
 * @since 2023-08-18
 */
@RestController
@RequestMapping("/sys/role")
@Slf4j
public class SysRoleController {
    public static List<String> roleCodeList = new ArrayList<>();
    static{
        roleCodeList.add(CommonConstant.Custom_admin);
        roleCodeList.add(CommonConstant.Repair_admin);
        roleCodeList.add(CommonConstant.Maintenance_leader);
        roleCodeList.add(CommonConstant.Maintenance_admin);
        roleCodeList.add(CommonConstant.Driver);
        roleCodeList.add(CommonConstant.Legal_admin);
        roleCodeList.add(CommonConstant.Market_admin);
    }
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private ISysPermissionService sysPermissionService;
    @Autowired
    private ISysUserRoleService sysUserRoleService;

    /**
     * 分页列表查询
     *
     * @param role
     * @param pageNo
     * @param pageSize
     * @return
     */
    @AddSysLog("查询角色列表")
    @GetMapping("/list")
    public Result<IPage<SysRole>> queryPageList(SysRole role, String column, String order,
                                                @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Result<IPage<SysRole>> result = new Result<>();
        if(StringUtils.isBlank(column)){
            column = "create_time";
            order = "desc";
        }
        QueryWrapper<SysRole> queryWrapper = QueryWrapperUtil.builder()
                .table(SysRole.class)
                .like(SysRole::getRoleCode)
                .like(SysRole::getRoleName)
                .orderColums(column)
                .orders(order)
                .buildFromObject(role);
        Page<SysRole> page = new Page<>(pageNo, pageSize);
        IPage<SysRole> pageList = sysRoleService.page(page, queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    /**
     * 添加角色
     *
     * @param role
     * @return
     */
    @AddSysLog("添加角色")
    @PostMapping("/add")
    public Result<SysRole> add(@RequestBody SysRole role) {
        ParamsCheckUtil.paramsAssert()
                .notBlank(role.getRoleName(), "【角色名称】不能为空！")
                .notBlank(role.getRoleCode(), "【角色编码】不能为空!")
                .isTrue(sysRoleService.lambdaQuery().eq(SysRole::getRoleCode, role.getRoleCode()).count()==0, "【角色编码】已存在！")
                .isTrue(sysRoleService.lambdaQuery().eq(SysRole::getRoleName, role.getRoleName()).count()==0, "【角色名称】已存在！")
        ;
        try {
            role.setCreateTime(new Date());
            sysRoleService.save(role);
            return Result.ok("添加成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.ok("操作失败!");
        }
    }

    /**
     * 编辑
     *
     * @param role
     * @return
     */
    @AddSysLog("编辑角色")
    @PutMapping("/edit")
    public Result<SysRole> edit(@RequestBody SysRole role) {
        ParamsCheckUtil.paramsAssert()
                .notBlank(role.getId(), "【角色ID】不能为空！")
                .notBlank(role.getRoleName(), "【角色名称】不能为空！")
                .notBlank(role.getRoleCode(), "【角色编码】不能为空!")
                .isTrue(sysRoleService.lambdaQuery().ne(SysRole::getId, role.getId()).eq(SysRole::getRoleCode, role.getRoleCode()).count()==0, "【角色编码】已存在！")
                .isTrue(sysRoleService.lambdaQuery().ne(SysRole::getId, role.getId()).eq(SysRole::getRoleName, role.getRoleName()).count()==0, "【角色名称】已存在！")
        ;
        SysRole sysrole = sysRoleService.getById(role.getId());
        if(roleCodeList.contains(sysrole.getRoleCode())){
            return Result.error("内置角色，不允许编辑！");
        }
        if (sysrole == null) {
            return Result.error("角色不存在！");
        } else {
            sysRoleService.updateById(role);
            return Result.ok("修改成功!");
        }
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AddSysLog("删除角色")
    @DeleteMapping("/delete")
    public Result<?> delete(String id) {
        ParamsCheckUtil.paramsAssert()
                .notBlank(id, "角色ID不能为空！")
                .isTrue(sysUserRoleService.lambdaQuery().eq(SysUserRole::getRoleId, id).count()==0, "角色已被使用，无法删除！")
        ;
        SysRole sysrole = sysRoleService.getById(id);
        if(roleCodeList.contains(sysrole.getRoleCode())){
            return Result.error("内置角色，不允许删除！");
        }
        sysRoleService.deleteRole(id);
        return Result.ok("删除角色成功");
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AddSysLog("批量删除角色")
    @DeleteMapping("/deleteBatch")
    public Result<SysRole> deleteBatch(String ids) {
        Result<SysRole> result = new Result<SysRole>();
        if (StringUtils.isBlank(ids)) {
            result.error500("未选中角色！");
        } else {
            ParamsCheckUtil.paramsAssert()
            .isTrue(sysUserRoleService.lambdaQuery().in(SysUserRole::getRoleId, Arrays.asList(ids.split(","))).count()==0, "角色已被使用，无法删除！")
            ;
            sysRoleService.deleteBatchRole(ids.split(","));
            result.success("删除角色成功!");
        }
        return result;
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AddSysLog("通过id查询角色")
    @GetMapping(value = "/queryById")
    public Result<SysRole> queryById(String id) {
        Result<SysRole> result = new Result<SysRole>();
        SysRole sysrole = sysRoleService.getById(id);
        if (sysrole == null) {
            result.error500("未找到对应实体");
        } else {
            result.setResult(sysrole);
            result.setSuccess(true);
        }
        return result;
    }

    @AddSysLog("查询所有角色")
    @GetMapping("/queryall")
    public Result<List<SysRole>> queryall() {
        List<SysRole> list = sysRoleService.list();
        if (list == null || list.size() <= 0) {
            return Result.error("未找到角色信息");
        } else {
            return Result.ok(list);
        }
    }

    /**
     * 校验角色编码唯一
     */
    @GetMapping("/checkRoleCode")
    public Result<Boolean> checkUsername(String id, String roleCode) {
        Result<Boolean> result = new Result<>();
        result.setResult(true);//如果此参数为false则程序发生异常
        log.info("--验证角色编码是否唯一---id:" + id + "--roleCode:" + roleCode);
        try {
            SysRole role = null;
            if (StringUtils.isNotBlank(id)) {
                role = sysRoleService.getById(id);
            }
            SysRole newRole = sysRoleService.getOne(new QueryWrapper<SysRole>().lambda().eq(SysRole::getRoleCode, roleCode));
            if (newRole != null) {
                //如果根据传入的roleCode查询到信息了，那么就需要做校验了。
                if (role == null) {
                    //role为空=>新增模式=>只要roleCode存在则返回false
                    result.setSuccess(false);
                    result.setMessage("角色编码已存在");
                    return result;
                } else if (!id.equals(newRole.getId())) {
                    //否则=>编辑模式=>判断两者ID是否一致-
                    result.setSuccess(false);
                    result.setMessage("角色编码已存在");
                    return result;
                }
            }
        } catch (Exception e) {
            result.setSuccess(false);
            result.setResult(false);
            result.setMessage(e.getMessage());
            return result;
        }
        result.setSuccess(true);
        return result;
    }

    /**
     * 用户角色授权功能，查询菜单权限树
     *
     * @return
     */
    @AddSysLog("查询角色树")
    @GetMapping("/queryTreeList")
    public Result<Map<String, Object>> queryTreeList() {
        //全部权限ids
        List<String> ids = new ArrayList<>();
        try {
            LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<SysPermission>();
            query.orderByAsc(SysPermission::getSortNo);
            List<SysPermission> list = sysPermissionService.list(query);
            for (SysPermission sysPer : list) {
                ids.add(sysPer.getId());
            }
            List<TreeModel> treeList = new ArrayList<>();
            getTreeModelList(treeList, list, null);
            Map<String, Object> resMap = new HashMap<>();
            resMap.put("treeList", treeList); //全部树节点数据
            resMap.put("ids", ids);//全部树ids
            return Result.ok(resMap);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

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