/**
 * 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.SecurityUtils;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.common.constant.CacheNames;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.sys.domain.SysParameterValue;
import com.jeeplus.sys.mapper.OfficeMapper;
import com.jeeplus.sys.service.DataRuleService;
import com.jeeplus.sys.service.MenuService;
import com.jeeplus.sys.service.UserService;
import com.jeeplus.sys.service.dto.*;
import com.jeeplus.sys.service.mapstruct.MenuWrapper;
import com.jeeplus.sys.sms.SMSUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

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 {

    private static OfficeMapper officeMapper = SpringUtil.getBean(OfficeMapper.class);

    private static UserService userService = SpringContextHolder.getBean(UserService.class);

    /**
     * 根据用户名获取用户
     * @param name
     * @return 取不到返回null
     */
    @InterceptorIgnore
    public static UserDTO getByName(String name){
        UserDTO userDTO = userService.getUserByName ( name );
        return userDTO;
    }

    /**
     * 根据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, String tenantId) {
        UserDTO userDTO = SpringUtil.getBean ( UserService.class ).getUserByLoginName ( loginName, tenantId );
        return userDTO;
    }

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


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

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

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

    public static List <MenuDTO> getMenuDTOListByLoginName(String loginName, String tenantId) {
        UserDTO user = getByLoginName ( loginName, tenantId );
        List <MenuDTO> menuDTOList = (List <MenuDTO>) RedisUtils.getInstance ( ).get ( CacheNames.USER_CACHE_MENU_LIST, user.getIdCacheKey ( ) );
        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.getIdCacheKey ( ), menuDTOList );
        }
        return menuDTOList;
    }


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

    public static List <DataRuleDTO> getDataRuleListByUserId(String userId) {
        UserDTO userDTO = SpringUtil.getBean ( UserService.class ).get ( userId );
        if ( userDTO.isAdmin ( ) ) {
            return Lists.newArrayList ( );
        } else {
            return SpringUtil.getBean ( DataRuleService.class ).findByUserId ( userId );
        }
    }

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

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

    public static Set <String> getPermissionsByLoginName(String loginName, String tenantId) {
        Set <String> info = new HashSet <> ( );
        List <MenuDTO> list = UserUtils.getMenuDTOListByLoginName ( loginName, tenantId );
        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, String tenantId) {
        if ( loginName != null && loginName.equals ( oldLoginName ) ) {
            return true;
        } else if ( loginName != null && SpringUtil.getBean ( UserService.class ).getUserByLoginName ( loginName, tenantId ) == null ) {
            return true;
        }
        return false;
    }

    /**
     * 获取系统参数
     * parameter 参数类型
     * branchOffice 分公司Id 分公司id为空传公司id
     * @return
     */
    public static String getSysParam(String parameter) {
        //查询当前登录人公司信息
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        OfficeDTO companyDTO = userDTO.getCompanyDTO();
        //当前登录人所属公司是子公司
        if (!"0".equals(companyDTO.getParentId()) && "1".equals(companyDTO.getType())) {
            //查询子公司简称
            if ("branch_shortname".equals(parameter)) {
                SysParameterValue sysParameterValue = officeMapper.findValueByParameter(parameter, companyDTO.getId());
                return sysParameterValue == null ? "" : sysParameterValue.getValue();
            }
            //查询公司简称
            if ("company_shortname".equals(parameter)) {
                SysParameterValue sysParameterValue = officeMapper.findValueByParameter(parameter, companyDTO.getParentId());
                return sysParameterValue == null ? "" : sysParameterValue.getValue();
            }
        } else {
            //当前登录人所属公司是总公司
            //查询公司简称
            if ("company_shortname".equals(parameter)) {
                SysParameterValue sysParameterValue = officeMapper.findValueByParameter(parameter, companyDTO.getId());
                return sysParameterValue == null ? "" : sysParameterValue.getValue();
            }
        }
        return "";
    }

    /**
     * 获取系统参数
     * parameter 参数类型
     * branchOffice 分公司Id 分公司id为空传公司id
     * @return
     */
    public static String getSysParamByToken(String parameter,String token) {
        //查询当前登录人公司信息
//        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        String loginName = TokenProvider.getLoginName(token);
        String tenantId = TenantUtils.getTenantId ( );
        UserDTO userDTO = UserUtils.getByLoginName(loginName, tenantId);
        OfficeDTO companyDTO = userDTO.getCompanyDTO();
        //当前登录人所属公司是子公司
        if (!"0".equals(companyDTO.getParentId()) && "1".equals(companyDTO.getType())) {
            //查询子公司简称
            if ("branch_shortname".equals(parameter)) {
                SysParameterValue sysParameterValue = officeMapper.findValueByParameter(parameter, companyDTO.getId());
                return sysParameterValue == null ? "" : sysParameterValue.getValue();
            }
            //查询公司简称
            if ("company_shortname".equals(parameter)) {
                SysParameterValue sysParameterValue = officeMapper.findValueByParameter(parameter, companyDTO.getParentId());
                return sysParameterValue == null ? "" : sysParameterValue.getValue();
            }
        } else {
            //当前登录人所属公司是总公司
            //查询公司简称
            if ("company_shortname".equals(parameter)) {
                SysParameterValue sysParameterValue = officeMapper.findValueByParameter(parameter, companyDTO.getId());
                return sysParameterValue == null ? "" : sysParameterValue.getValue();
            }
        }
        return "";
    }

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

    }


}
