package com.njcn.gather.user.user.controller;

import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.JwtUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.gather.user.user.pojo.param.SysFunctionParam;
import com.njcn.gather.user.user.pojo.param.SysRoleParam;
import com.njcn.gather.user.user.pojo.po.SysFunction;
import com.njcn.gather.user.user.pojo.vo.MenuVO;
import com.njcn.gather.user.user.service.ISysFunctionService;
import com.njcn.gather.user.user.service.ISysRoleFunctionService;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.HttpResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;


/**
 * @author caozehui
 * @date 2024-11-15
 */
@Slf4j
@Api(tags = "菜单（资源）管理")
@RestController
@RequestMapping("/sysFunction")
@RequiredArgsConstructor
public class SysFunctionController extends BaseController {
    private final ISysFunctionService sysFunctionService;
    private final ISysRoleFunctionService sysRoleFunctionService;

    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getTree")
    @ApiOperation("按照名称模糊查询菜单树")
    @ApiImplicitParam(name = "keyword", value = "查询参数", required = true)
    public HttpResult<List<SysFunction>> getFunctionTreeByKeyword(@RequestParam @Validated String keyword) {
        String methodDescribe = getMethodDescribe("getFunctionTreeByKeyword");
        LogUtil.njcnDebug(log, "{}，查询数据为：{}", methodDescribe, keyword);
        List<SysFunction> result = sysFunctionService.getFunctionTreeByKeyword(keyword);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/functionTreeNoButton")
    @ApiOperation("菜单树-不包括按钮")
    public HttpResult<List<SysFunction>> getFunctionTreeNoButton() {
        String methodDescribe = getMethodDescribe("getFunctionTreeNoButton");
        List<SysFunction> list = sysFunctionService.getFunctionTree(false);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, list, methodDescribe);
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
    @PostMapping("/add")
    @ApiOperation("新增菜单")
    @ApiImplicitParam(name = "functionParam", value = "菜单数据", required = true)
    public HttpResult<Boolean> add(@RequestBody @Validated SysFunctionParam functionParam) {
        String methodDescribe = getMethodDescribe("add");
        LogUtil.njcnDebug(log, "{}，菜单数据为：{}", methodDescribe, functionParam);
        boolean result = sysFunctionService.addFunction(functionParam);
        if (result) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
        }
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
    @PostMapping("/update")
    @ApiOperation("修改菜单")
    @ApiImplicitParam(name = "functionParam", value = "菜单数据", required = true)
    public HttpResult<Boolean> update(@RequestBody @Validated SysFunctionParam.UpdateParam functionParam) {
        String methodDescribe = getMethodDescribe("update");
        LogUtil.njcnDebug(log, "{},更新的菜单信息为：{}", methodDescribe, functionParam);
        boolean result = sysFunctionService.updateFunction(functionParam);
        if (result) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
        }
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DELETE)
    @PostMapping("/delete")
    @ApiOperation("删除菜单")
    @ApiImplicitParam(name = "id", value = "菜单id", required = true)
    public HttpResult<Boolean> delete(@RequestParam String id) {
        String methodDescribe = getMethodDescribe("delete");
        LogUtil.njcnDebug(log, "{},删除的菜单id为：{}", methodDescribe, id);
        boolean result = sysFunctionService.deleteFunction(id);
        if (result) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
        }
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getMenu")
    @ApiOperation("获取菜单")
    public HttpResult<List<MenuVO>> getMenu(HttpServletRequest request) {
        String methodDescribe = getMethodDescribe("getMenu");
        String tokenStr = request.getHeader(SecurityConstants.AUTHORIZATION_KEY);
        if (StrUtil.isNotBlank(tokenStr)) {
            tokenStr = tokenStr.replace(SecurityConstants.AUTHORIZATION_PREFIX, Strings.EMPTY);
            String userId = (String) (JwtUtil.parseToken(tokenStr).get("userId"));
            List<MenuVO> list = sysFunctionService.getMenuByUserId(userId);
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, list, methodDescribe);
        }
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getButton")
    @ApiOperation("获取按钮")
    public HttpResult<Map<String, List<String>>> getButton(HttpServletRequest request) {
        String methodDescribe = getMethodDescribe("getButton");
        String tokenStr = request.getHeader(SecurityConstants.AUTHORIZATION_KEY);
        if (StrUtil.isNotBlank(tokenStr)) {
            tokenStr = tokenStr.replace(SecurityConstants.AUTHORIZATION_PREFIX, Strings.EMPTY);
            String userId = (String) JwtUtil.parseToken(tokenStr).get("userId");
            Map<String, List<String>> map = sysFunctionService.getButtonByUserId(userId);
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, map, methodDescribe);
        }
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @PostMapping("/getFunctionsByRoleId")
    @ApiOperation("获取角色id绑定的菜单（资源）")
    @ApiImplicitParam(name = "id", value = "角色id", required = true)
    public HttpResult<List<SysFunction>> getFunctionsByRoleId(@RequestParam @Validated String id) {
        String methodDescribe = getMethodDescribe("getFunctionsByRoleId");
        LogUtil.njcnDebug(log, "{}，查询数据为：{}", methodDescribe, id);
        List<SysFunction> sysFunctions = sysRoleFunctionService.listFunctionByRoleId(id);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, sysFunctions, methodDescribe);
    }

    @OperateInfo(operateType = OperateType.UPDATE, info = LogEnum.SYSTEM_MEDIUM)
    @PostMapping("/assignFunctionByRoleId")
    @ApiOperation("角色分配菜单")
    @ApiImplicitParam(name = "param", value = "角色信息", required = true)
    public HttpResult<Boolean> assignFunctionByRoleId(@RequestBody @Validated SysRoleParam.RoleBindFunction param) {
        String methodDescribe = getMethodDescribe("assignFunctionByRoleId");
        LogUtil.njcnDebug(log, "{},传入的角色id和资源id集合为：{}", methodDescribe, param);
        boolean result = sysRoleFunctionService.updateRoleFunction(param.getRoleId(), param.getFunctionIds());
        if (result) {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, false, methodDescribe);
        }
    }
}

