/**
 * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.sys.utils;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.google.common.collect.Lists;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.security.util.SecurityUtils;
import com.jeeplus.sys.constant.CacheNames;
import com.jeeplus.sys.service.DataRuleService;
import com.jeeplus.sys.service.MenuService;
import com.jeeplus.sys.service.UserService;
import com.jeeplus.sys.service.dto.DataRuleDTO;
import com.jeeplus.sys.service.dto.MenuDTO;
import com.jeeplus.sys.service.dto.RoleDTO;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.service.mapstruct.MenuWrapper;
import com.jeeplus.sys.sms.SMSUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 用户工具类
 *
 * @author jeeplus
 * @version 2021-06-05
 */
public class UserUtils {


    /**
     * 根据ID获取用户
     *
     * @param id
     * @return 取不到返回null
     */
    public static UserDTO get(String id) {
        UserDTO userDTO = (UserDTO) RedisUtils.getInstance ( ).get ( CacheNames.USER_CACHE_USER_ID, id );

        if ( userDTO == null ) {
            userDTO = SpringUtil.getBean ( UserService.class ).get ( id );
        }
        return userDTO;
    }

    /**
     * 根据登录名获取用户
     *
     * @param loginName
     * @return 取不到返回null
     */
    @InterceptorIgnore
    public static UserDTO getByLoginName(String loginName) {
        if(StrUtil.isEmpty ( loginName )){
            return new UserDTO (  );
        }
        UserDTO userDTO = SpringUtil.getBean ( UserService.class ).getUserByLoginName ( loginName );
        return userDTO;
    }

    /**
     * 清除当前用户缓存
     */
    public static void deleteCache(UserDTO userDTO) {
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_USER_ID, userDTO.getId ( ) );
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_DATA_RULE_LIST, userDTO.getId ( ) );
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_MENU_LIST, userDTO.getId ( ) );
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_ROLE_LIST, userDTO.getId ( ) );
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_TOP_MENU, userDTO.getId ( ) );
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_LOGIN_NAME, userDTO.getLoginName ( ) );
        RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_LOGIN_NAME, userDTO.getOldLoginName ( ) );
    }


    /**
     * 获取当前用户
     *
     * @return 取不到返回 new User()
     */
    public static UserDTO getCurrentUserDTO() {
        String username = SecurityUtils.getLoginName ( );
        if ( StrUtil.isNotEmpty ( username ) ) {
            return getByLoginName ( username );
        }
        return new UserDTO ( );
    }

    /**
     * 获取当前用户角色列表
     *
     * @return
     */
    public static List <RoleDTO> getRoleDTOList() {
        return getCurrentUserDTO ( ).getRoleDTOList ( );
    }

    /**
     * 获取当前用户授权菜单， admin用户不受角色权限控制可以获取全部菜单
     *
     * @return
     */
    public static List <MenuDTO> getMenuDTOList() {
        String loginName = SecurityUtils.getLoginName ( );
        return getMenuDTOListByLoginName ( loginName );
    }


    public static List <MenuDTO> getMenuDTOListByLoginName(String loginName) {
        UserDTO user = UserUtils.getByLoginName ( loginName );
        List <MenuDTO> menuDTOList = (List <MenuDTO>) RedisUtils.getInstance ( ).get ( CacheNames.USER_CACHE_MENU_LIST, user.getId ( ) );
        if ( menuDTOList == null ) {

            if ( user.isAdmin ( ) ) {
                menuDTOList = SpringUtil.getBean ( MenuService.class ).findList ( );
            } else {
                menuDTOList = SpringUtil.getBean ( MenuService.class ).findByUserId ( user.getId ( ) );
            }
            RedisUtils.getInstance ( ).set ( CacheNames.USER_CACHE_MENU_LIST, user.getId ( ), menuDTOList );
        }
        return menuDTOList;
    }

    /**
     * 获取当前用户授权数据权限， admin用户不受数据权限限制可以访问全部数据
     *
     * @return
     */
    public static List <DataRuleDTO> getDataRuleList() {
        UserDTO userDTO = getCurrentUserDTO ( );
        if ( userDTO.isAdmin ( ) ) {
            return Lists.newArrayList ( );
        } else {
            return SpringUtil.getBean ( DataRuleService.class ).findByUserId ( userDTO.getId () );
        }
    }

    /**
     * 获取当前用户授权菜单
     *
     * @return
     */
    public static MenuDTO getTopMenuDTO() {
        MenuDTO topMenuDTO = (MenuDTO) RedisUtils.getInstance ( ).get ( CacheNames.USER_CACHE_TOP_MENU, getCurrentUserDTO ( ).getId ( ) );
        if ( topMenuDTO == null ) {
            topMenuDTO = MenuWrapper.INSTANCE.toDTO ( SpringUtil.getBean ( MenuService.class ).getById ( "1" ) );
            RedisUtils.getInstance ( ).set ( CacheNames.USER_CACHE_TOP_MENU, getCurrentUserDTO ( ).getId ( ), topMenuDTO );
        }
        return topMenuDTO;
    }


    /**
     * 获取用户权限
     *
     * @return
     */
    public static Set <String> getPermissions() {
        return getPermissionsByLoginName ( SecurityUtils.getLoginName ( ) );
    }

    public static Set <String> getPermissionsByLoginName(String loginName) {
        Set <String> info = new HashSet <> ( );
        List <MenuDTO> list = UserUtils.getMenuDTOListByLoginName ( loginName );
        for (MenuDTO menuDTO : list) {
            if ( StrUtil.isNotBlank ( menuDTO.getPermission ( ) ) ) {
                for (String permission : StrUtil.split ( menuDTO.getPermission ( ), "," )) {
                    info.add ( permission );
                }
            }
        }
        return info;
    }

    /**
     * 获取在线用户列表
     */
    public static List <UserDTO> getOnlineUsers() {
        Set <String> keys = RedisUtils.getInstance ( ).keys ( CacheNames.USER_CACHE_ONLINE_USERS, "*" );
        List <UserDTO> onlineUsers = Lists.newArrayList ( );
        keys.forEach ( key -> {
            onlineUsers.add ( (UserDTO) RedisUtils.getInstance ( ).get ( key ) );
        } );
        return onlineUsers;
    }


    /**
     * 检验用户名是否唯一
     */
    public static boolean isCheckLoginName(String oldLoginName, String loginName) {
        if ( loginName != null && loginName.equals ( oldLoginName ) ) {
            return true;
        } else if ( loginName != null && SpringUtil.getBean ( UserService.class ).getUserByLoginName ( loginName ) == null ) {
            return true;
        }
        return false;
    }

    //容联云通讯
    public static HashMap<String,Object> sendRandomCodes(String mobile, String randomCode) throws IOException {
        return SMSUtils.sends(mobile, randomCode);

    }


}
