package com.yida.data.system.controller;

import com.yida.data.common.core.annotation.ControllerLog;
import com.yida.data.common.core.common.ModuleName;
import com.yida.data.common.core.entity.FebsResponse;
import com.yida.data.common.core.entity.constant.StringConstant;
import com.yida.data.common.core.entity.router.VueRouter;
import com.yida.data.common.core.entity.system.Menu;
import com.yida.data.common.core.entity.system.Role;
import com.yida.data.common.core.entity.system.enums.OperationLogTypeEnum;
import com.yida.data.log.annotation.OperationLog;
import com.yida.data.system.service.IMenuService;
import com.yida.data.system.service.IRoleService;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author MrBird
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/menu")
public class MenuController {

    private final IMenuService menuService;

    private final IRoleService roleService;

    @GetMapping("/{username}")
    public FebsResponse getUserRouters(@NotBlank(message = "{required}") @PathVariable String username) {
        Map<String, Object> result = new HashMap<>(4);
        List<VueRouter<Menu>> userRouters = this.menuService.getUserRouters(username);
        List<Menu> userRealMenus = this.menuService.findUserRealMenus(username, null);
        String userPermissions = userRealMenus.stream().map(Menu::getPerms).collect(Collectors.joining(StringConstant.COMMA));
        List<Role> userRoleList = this.roleService.findUserRole(username);
        List<Role> mainRoleList = this.roleService.findMainRole(username);

        String[] permissionArray = new String[0];
        if (StringUtils.isNoneBlank(userPermissions)) {
            permissionArray = StringUtils.splitByWholeSeparatorPreserveAllTokens(userPermissions, StringConstant.COMMA);
        }
        // 判断登录用户角色信息
        String[] roleArray = new String[0];
        if (!CollectionUtils.isEmpty(userRoleList)) {
            String userRoles = userRoleList.stream()
                .filter(role -> Objects.nonNull(role) && StringUtils.isNotBlank(role.getRolePerms()))
                .map(Role::getRolePerms)
                .collect(Collectors.joining(StringConstant.COMMA));
            if (StringUtils.isNoneBlank(userPermissions)) {
                roleArray = StringUtils.splitByWholeSeparatorPreserveAllTokens(userRoles, StringConstant.COMMA);
            }
        }
        // 判断登录主角色信息
        String[] mainRoleArray = new String[0];
        if (!CollectionUtils.isEmpty(mainRoleList)) {
            String mainRoles = mainRoleList.stream()
                .filter(role -> Objects.nonNull(role) && StringUtils.isNotBlank(role.getRolePerms()))
                .map(Role::getRolePerms)
                .collect(Collectors.joining(StringConstant.COMMA));
            if (StringUtils.isNoneBlank(mainRoles)) {
                mainRoleArray = StringUtils.splitByWholeSeparatorPreserveAllTokens(mainRoles, StringConstant.COMMA);
            }
        }

        result.put("routes", userRouters);
        result.put("permissions", permissionArray);
        result.put("roles", roleArray);
        result.put("mainRoles", mainRoleArray);
        return new FebsResponse().data(result);
    }

    @GetMapping
    public FebsResponse menuList(Menu menu) {
        Map<String, Object> menus = this.menuService.findMenus(menu);
        return new FebsResponse().data(menus);
    }

    @GetMapping("/permissions")
    public String findUserPermissions(String username) {
        return this.menuService.findUserPermissions(username);
    }

    @PostMapping
    @PreAuthorize("hasAuthority('menu:add')")
    @OperationLog(module = ModuleName.SYSTEM, methods = "新增菜单/按钮", type = OperationLogTypeEnum.INSERT)
    public void addMenu(@Valid Menu menu) {
        this.menuService.createMenu(menu);
    }

    @DeleteMapping("/{menuIds}")
    @PreAuthorize("hasAuthority('menu:delete')")
    @OperationLog(module = ModuleName.SYSTEM, methods = "删除菜单/按钮", type = OperationLogTypeEnum.DELETE)
    public void deleteMenus(@NotBlank(message = "{required}") @PathVariable String menuIds) {
        String[] ids = menuIds.split(StringConstant.COMMA);
        this.menuService.deleteMeuns(ids);
    }

    @PutMapping
    @PreAuthorize("hasAuthority('menu:update')")
    @OperationLog(module = ModuleName.SYSTEM, methods = "修改菜单/按钮", type = OperationLogTypeEnum.UPDATE)
    public void updateMenu(@Valid Menu menu) {
        this.menuService.updateMenu(menu);
    }

    @PostMapping("excel")
    @PreAuthorize("hasAuthority('menu:export')")
    public void export(Menu menu, HttpServletResponse response) {
        List<Menu> menus = this.menuService.findMenuList(menu);
        //ExcelKit.$Export(Menu.class, response).downXlsx(menus, false);
    }

    @ApiOperation("根据登录账号查询菜单数, 角色相关菜单数据")
    @GetMapping("/listMenuByUserNameNoCheck")
    public FebsResponse listMenuByUserNameNoCheck(@RequestParam String username) {
        Map<String, Object> menus = this.menuService.listMenuByUserNameNoCheck(username);
        return new FebsResponse().data(menus);
    }
}