package com.bweb.controller;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.ResponseMsgUtil;
import com.hfkj.entity.SecMenu;
import com.hfkj.entity.SecRoleMenuRel;
import com.hfkj.model.ResponseData;
import com.hfkj.service.SecMenuService;
import com.hfkj.service.SecRoleMenuRelService;
import com.hfkj.sysenum.SecMenuTypeEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @className: SecMenu
 * @author: HuRui
 * @date: 2024/3/28
 **/
@Controller
@RequestMapping(value="/secMenu")
@Api(value="系统菜单管理")
public class SecMenuController {

    Logger log = LoggerFactory.getLogger(SecUserController.class);

    @Resource
    private SecMenuService secMenuService;
    @Resource
    private SecRoleMenuRelService secRoleMenuRelService;

    @RequestMapping(value="/editMenu",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "编辑菜单")
    public ResponseData editMenu(@RequestBody SecMenu body) {
        try {
            if (body == null
                    || body.getMenuType() == null
                    || StringUtils.isBlank(body.getMenuName())
                    || StringUtils.isBlank(body.getMenuUrl())
                    || body.getMenuSort() == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            SecMenu secMenu;

            if (body.getId() != null) {
                // 查询菜单
                secMenu = secMenuService.queryDetail(body.getId());
                if (secMenu == null) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
                }
            } else {
                secMenu = new SecMenu();
            }
            if (secMenu.getMenuPSid() != null) {
                // 查询父类菜单
                SecMenu parentMenu = secMenuService.queryDetail(secMenu.getMenuPSid());
                if (parentMenu == null) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
                }
            }

            secMenu.setMenuType(body.getMenuType());
            secMenu.setMenuName(body.getMenuName());
            secMenu.setMenuUrl(body.getMenuUrl());
            secMenu.setMenuUrlImg(body.getMenuUrlImg());
            secMenu.setMenuPSid(body.getMenuPSid());
            secMenu.setMenuSort(body.getMenuSort());
            secMenu.setMenuDesc(body.getMenuDesc());
            if (secMenu.getId() == null) {
                secMenuService.create(secMenu);
            } else {
                secMenuService.update(secMenu);
            }
            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/queryDetail",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "查询详情")
    public ResponseData queryDetail(@RequestParam(value = "menuId" , required = true) Long menuId) {
        try {

            return ResponseMsgUtil.success(secMenuService.queryDetail(menuId));

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/delMenu",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "删除菜单")
    public ResponseData delMenu(@RequestBody JSONObject body) {
        try {
            if (body == null || body.getLong("menuId") == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            secMenuService.delete(body.getLong("menuId"));

            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/assignMenu",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "分配菜单")
    public ResponseData assignMenu(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || body.getLong("roleId") == null
                    || body.getJSONArray("menuIds").isEmpty()) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }

            List<Long> list = body.getJSONArray("menuIds")
                    .stream().map(o -> Long.parseLong(o.toString()))
                    .collect(Collectors.toList());

            secMenuService.assignMenu(body.getLong("roleId"),list );
            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/queryMenuList",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "查询菜单列表")
    public ResponseData queryMenuList() {
        try {

            return ResponseMsgUtil.success(secMenuService.getAllList());

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/queryRoleMenuArray",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询分配菜单树")
    public ResponseData queryRoleMenuArray(@RequestParam(value = "roleId" , required = true) Long roleId) {
        try {

            // 查询角色菜单权限
            List<SecRoleMenuRel> roleMenuList = secRoleMenuRelService.getRelListByRole(roleId);

            return ResponseMsgUtil.success(roleMenuList.stream().map(SecRoleMenuRel::getMenuId).collect(Collectors.toList())
                    .stream().map(Object::toString).collect(Collectors.toList()));

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/queryRoleMenuTree",method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询角色菜单树")
    public ResponseData queryRoleMenuTree(@RequestParam(value = "roleId" , required = false) Long roleId) {
        try {

            return ResponseMsgUtil.success(secMenuService.queryMenuTree(roleId));

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="/queryMenuTree",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "查询角色菜单树")
    public ResponseData queryMenuTree() {
        try {
            List<Map<String,Object>> mapList = new ArrayList<>();
            Map<String,Object> map;

            // 获取全部菜单
            List<SecMenu> menuList = secMenuService.getAllList();

            // 获取最顶层菜单
            List<SecMenu> topLevelMenuList = menuList.stream()
                    .filter(o -> o.getMenuPSid() == null)
                    .sorted(Comparator.comparing(SecMenu::getMenuSort))
                    .collect(Collectors.toList());

            for (SecMenu topLevelMenu : topLevelMenuList) {
                if (topLevelMenu.getMenuType().equals(SecMenuTypeEnum.type1.getCode())) {
                    map = new HashMap<>();
                    map.put("key", ""+topLevelMenu.getId());
                    map.put("title", topLevelMenu.getMenuName());
                    // 获取下级菜单
                    map.put("children", recursionMenu(menuList, topLevelMenu.getId()));
                    mapList.add(map);
                }
            }

            return ResponseMsgUtil.success(mapList);

        } catch (Exception e) {
            log.error("error!",e);
            return ResponseMsgUtil.exception(e);
        }
    }

    /**
     * 递归获取菜单
     * @param dataSource 数据源
     * @param parentMenuId 父级菜单id
     * @return
     */
    public List<Map<String,Object>> recursionMenu(List<SecMenu> dataSource, Long parentMenuId) {
        List<Map<String,Object>> mapList = new ArrayList<>();
        Map<String,Object> map;

        List<SecMenu> collect = dataSource.stream()
                .filter(o -> o.getMenuPSid() != null && o.getMenuPSid().equals(parentMenuId))
                .sorted(Comparator.comparing(SecMenu::getMenuSort))
                .collect(Collectors.toList());
        for (SecMenu menu : collect) {
            if (menu.getMenuType().equals(SecMenuTypeEnum.type1.getCode())) {
                map = new HashMap<>();
                map.put("key", ""+menu.getId());
                map.put("title", menu.getMenuName());
                // 获取下级菜单
                List<Map<String, Object>> recursioned = recursionMenu(dataSource, menu.getId());
                if (recursioned.isEmpty()) {
                    map.put("isLeaf", true);
                } else {
                    map.put("children", recursioned);
                }
                mapList.add(map);
            }
        }
        return mapList;
    }

}
