package com.ruoyi.web.controller.system;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.MenuTypeEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.system.domain.grid.GridRegionUser;
import com.ruoyi.system.domain.grid.GridRegionUserExample;
import com.ruoyi.system.domain.grid.enums.GridRegionSearchParam;
import com.ruoyi.system.mapper.system.SysMenuMapper;
import com.ruoyi.system.service.grid.GridRegionService;
import com.ruoyi.system.service.grid.GridRegionUserService;
import com.ruoyi.system.service.system.ISysUserService;
import com.ruoyi.system.service.system.SysMenuPermissionService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.system.service.system.ISysMenuService;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@Api(tags = "基础服务 - 登录验证")
@RestController
public class SysLoginController {
    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private GridRegionUserService gridRegionUserService;

    @Autowired
    private GridRegionService gridRegionService;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private SysMenuPermissionService sysMenuPermissionService;

    @Autowired
    private ISysUserService sysUserService;

    /**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid(), true);
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    @PostMapping("/app/login")
    public AjaxResult appLogin(@RequestBody LoginBody loginBody) {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), null, null, false);
        ajax.put(Constants.TOKEN, token);
        SysUser sysUser = sysUserService.selectUserByUserName(loginBody.getUsername());
        ajax.put("leaderFlag", sysUser == null?"0":sysUser.getLeaderFlag().toString());
        return ajax;
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
        Set<String> appPermissions = permissionService.getAppMenuPermission(user);
        //网格
        GridRegionUserExample example = new GridRegionUserExample();
        GridRegionUserExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(user.getUserId());
        criteria.andIsValidEqualTo("1");
        List<GridRegionUser> relationship = gridRegionUserService.selectByExample(example);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        ajax.put("appPermissionPath", appPermissions);
        ajax.put("region", CollectionUtils.isEmpty(relationship)?"":relationship.stream().map(GridRegionUser::getWgId).collect(Collectors.joining(",")));
        GridRegionSearchParam param = new GridRegionSearchParam();
        param.setWgCodeIn(relationship.stream().map(GridRegionUser::getWgId).collect(Collectors.toList()));
        ajax.put("regionList",CollectionUtils.isEmpty(relationship)?new ArrayList<>():gridRegionService.getByParams(param));
        //另写接口返回菜单权限
        //        List<SysMenu> menuList = permissionService.getMenuPermissionMenuList(user);
//        if(!CollectionUtils.isEmpty(menuList)){
//            for(SysMenu menu : menuList){
//                if(MenuTypeEnum.APP.getCode().equals(menu.getMenuType())){
//                    menu.setRootMenuId(menu.getMenuId());
//                }else{
//                    menu.setRootMenuId(getRootMenuId(menu));
//                }
//            }
//        }
//        ajax.put("menuList", menuList);
        return ajax;
    }

    private SysMenu getRootMenuId(SysMenu menu){
        if(menu.getParentId() != null){
            SysMenu sysMenu = menuService.selectMenuById(menu.getParentId());
            if(MenuTypeEnum.APP.getCode().equals(sysMenu.getMenuType())){
                return sysMenu;
            }else{
                return getRootMenuId(sysMenu);
            }
        }
        return menu;
    }

    /**
     * 当前用户是否有另一个路由path的权限，有则返回该菜单
     * @param path
     * @return
     */
    @GetMapping("hasRoutePermission")
    public AjaxResult hasRoutePermission(@RequestParam("path")String path){
        SysMenu param = new SysMenu();
        param.setStatus("0");
        param.setPath(path);
        List<SysMenu> sysMenuList = sysMenuMapper.selectMenuList(param);
        if(CollectionUtils.isEmpty(sysMenuList)){
            throw new ServiceException("无此菜单!");
        }
        SysMenu menu = sysMenuList.get(0);
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<Long> menuIds = new ArrayList<>();
        if (user.isAdmin()) {
            SysMenu sysMenu = new SysMenu();
            sysMenu.setStatus("0");
            List<SysMenu> menus = sysMenuMapper.selectMenuList(sysMenu);
            menuIds = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
        }else{
            menuIds = sysMenuPermissionService.getUserMenuIds(user, null);
        }
        if(!menuIds.contains(menu.getMenuId())){
            throw new ServiceException("无此路由权限!");
        }
        if(MenuTypeEnum.APP.getCode().equals(menu.getMenuType())){
            menu.setRootMenuId(menu.getMenuId());
            menu.setRootMenuName(menu.getMenuName());
        }else{
            SysMenu rootMenu = getRootMenuId(menu);
            menu.setRootMenuId(rootMenu.getMenuId());
            menu.setRootMenuName(rootMenu.getMenuName());
        }
        return AjaxResult.success(menu);
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters() {
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(loginUser);
        return AjaxResult.success(menuService.buildMenus(menus));
    }

    /**
     * 获取顶级菜单
     */
    @GetMapping("/app/list")
    public AjaxResult appList() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        List<SysMenu> menus = permissionService.getAppList(user);
        return AjaxResult.success(menus);
    }

    /**
     * 判断是否有权限
     *
     * @param appId
     * @return
     */
    @GetMapping("/app/hasPerms")
    public AjaxResult hasPerms(Long appId) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        return AjaxResult.success(permissionService.hasAppPerms(user, appId));
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("/app/getRouters")
    public AjaxResult getAppRouters(Long menuId) {
        if (menuId == null) {
            return AjaxResult.warn("应用id不能为空");
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(loginUser.getUser());

        for (SysMenu menu : menus) {
            if (menu.getMenuId().equals(menuId)) {
                return AjaxResult.success(menuService.buildMenus(menu.getChildren()));
            }
        }
        return AjaxResult.success();
    }
}
