package com.ho.user.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.constant.RedisKeyConstant;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.entity.SysPermission;
import com.ho.common.tools.entity.UserDetailRespVO;
import com.ho.common.tools.service.RedisService;
import com.ho.user.api.entity.SysUser;
import com.ho.user.mapper.SysPermissionMapper;
import com.ho.user.mapper.SysUserMapper;
import com.ho.user.service.*;
import com.ho.user.vo.req.UserPageReqVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Description TODO
 * Author yule
 * Date 2022/9/19 17:56
 */
@Service
@Slf4j
public class RedisUpdateServiceImpl implements RedisUpdateService {

    @Autowired
    RedisService redisService;


    @Autowired
    @Lazy
    DeptService deptService;

    @Autowired
    UserRoleService userRoleService;

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysPermissionMapper permissionMapper;

    @Autowired
    PermissionService permissionService;


    @Override
    public void updateRedis(UserDetailRespVO userDetail, SysUser sysUser) {
        String accessToken = userDetail.getAccessToken();
        //判断更新人是否是本人
        redisService.set(RedisKeyConstant.User.TOKEN + accessToken, userDetail, 2, TimeUnit.HOURS);
        //SimpleUser不需要改
        //redisService.set(RedisKeyConstant.User.USER_NAME +userDetail.getLoginChannel() + ":"+ userDetail.getUsername(), simpleUser, 2, TimeUnit.HOURS);
        //redisService.set(RedisKeyConstant.User.IDENTIFY_CACHE_KEY + sysUser.getId(), userDetail.getPowerList(), 2, TimeUnit.HOURS);
        redisService.delete(RedisKeyConstant.User.IDENTIFY_CACHE_KEY + sysUser.getId());

    }

    @Override
    public void cleanLoginInfosByRoleId(List<Integer> roleIds) {
        log.info("cleanLoginInfosByRoleId:" + roleIds);
        if (!roleIds.isEmpty()) {
            List<String> userIdsByRoleIds = userRoleService.getUserIdsByRoleIds(roleIds);
            if (userIdsByRoleIds.isEmpty()) {
                return;
            }
            for (String userId : userIdsByRoleIds) {
                //查用户信息
                SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
                if (sysUser != null) {
                    String userNameKeyPc = RedisKeyConstant.User.USER_NAME +RedisKeyConstant.User.LOGIN_CHANNEL_PC +":"+ sysUser.getUsername();
                    String userNameKeyApp = RedisKeyConstant.User.USER_NAME +RedisKeyConstant.User.LOGIN_CHANNEL_APP +":"+ sysUser.getUsername();
                    //如果有缓存就删除
                    if (redisService.hasKey(userNameKeyPc)) {
                        SimpleUser simpleUser = (SimpleUser) redisService.get(userNameKeyPc);
                        String token = simpleUser.getToken();
                        String tokenKey = RedisKeyConstant.User.TOKEN + token;
                        String shiroKey = RedisKeyConstant.User.IDENTIFY_CACHE_KEY + userId;
                        redisService.delete(userNameKeyPc);
                        redisService.delete(tokenKey);
                        redisService.delete(shiroKey);
                    }
                    if (redisService.hasKey(userNameKeyApp)) {
                        SimpleUser simpleUser = (SimpleUser) redisService.get(userNameKeyApp);
                        String token = simpleUser.getToken();
                        String tokenKey = RedisKeyConstant.User.TOKEN + token;
                        String shiroKey = RedisKeyConstant.User.IDENTIFY_CACHE_KEY + userId;
                        redisService.delete(userNameKeyApp);
                        redisService.delete(tokenKey);
                        redisService.delete(shiroKey);
                    }
                }
            }

        }
    }


    /**
     * 更新超管的菜单信息
     */
    @Override
    public void updateSuperPermsCache() {

        //根据超管查询出所有超管用户
        UserPageReqVO userPageReqVO = new UserPageReqVO();
        userPageReqVO.setSuperRole("super");
        List<SysUser> sysUsers = sysUserMapper.selectAll(userPageReqVO);

        //查询全部有效菜单
        SysPermission sysManageMenu = permissionService.findSysManageMenu();
        if (sysManageMenu != null) {
            List<SysPermission> menuList = new ArrayList<>();
            menuList.add(sysManageMenu);
            List<Integer> queryIds = new ArrayList<>();
            queryIds.add(sysManageMenu.getId());
            List<SysPermission> permissions = permissionService.getSysMangeMenus(menuList, queryIds);
            sysManageMenu.setChildren(getPermTree(sysManageMenu.getId(), permissions));
            //将菜单放入userDetail对象
            List<SysPermission> menus = new ArrayList<>();
            menus.add(sysManageMenu);

            //包含这个用户就更新这个用户的 menuList 和powerList
            if (!sysUsers.isEmpty()) {
                for (SysUser sysUser : sysUsers) {
                    String userNameKeyPc = RedisKeyConstant.User.USER_NAME + RedisKeyConstant.User.LOGIN_CHANNEL_PC + ":" + sysUser.getUsername();
                    String userNameKeyApp = RedisKeyConstant.User.USER_NAME + RedisKeyConstant.User.LOGIN_CHANNEL_APP + ":" + sysUser.getUsername();
                    //用户处于登陆状态
                    if (redisService.hasKey(userNameKeyPc)) {
                        SimpleUser simpleUser = (SimpleUser) redisService.get(userNameKeyPc);
                        if (simpleUser != null) {
                            String tokenKey = RedisKeyConstant.User.TOKEN + simpleUser.getToken();
                            UserDetailRespVO userDetail = (UserDetailRespVO) redisService.get(tokenKey);
                            if (userDetail != null) {
                                //userDetail.setMenuList(menus);
                                //userDetail.setPowerList(powerList);
                                redisService.set(tokenKey, userDetail, 2, TimeUnit.HOURS);
                            }
                        }
                    }
                    if (redisService.hasKey(userNameKeyApp)) {
                        SimpleUser simpleUser = (SimpleUser) redisService.get(userNameKeyApp);
                        if (simpleUser != null) {
                            String tokenKey = RedisKeyConstant.User.TOKEN + simpleUser.getToken();
                            UserDetailRespVO userDetail = (UserDetailRespVO) redisService.get(tokenKey);
                            if (userDetail != null) {
                                //userDetail.setMenuList(menus);
                                //userDetail.setPowerList(powerList);
                                redisService.set(tokenKey, userDetail, 2, TimeUnit.HOURS);
                            }
                        }
                    }
                }
            }

        }
    }

    public List<SysPermission> getPermTree(Integer id, List<SysPermission> permissions) {
        List<SysPermission> list = new ArrayList<>();
        for (SysPermission permission : permissions) {
            if (permission.getPid().equals(id) && CommonConstant.MENU_FLAG.equals(permission.getType())) {
                permission.setChildren(getPermTree(permission.getId(), permissions));
                list.add(permission);
            }
        }
        return list;
    }

    @Override
    public String getTokenKey() {
        return null;
    }

    @Override
    public String getUserNameKey(String userName) {
        //RedisKeyConstant.User.USER_NAME +loginReqVO.getType() + ":" + loginReqVO.getUsername()
        return null;
    }

    //找到所有超管的菜单
    /*private List<SysPermission> getSuperPerms() {
        UserPageReqVO userPageReqVO = new UserPageReqVO();
        userPageReqVO.setSuperRole("super");
        List<SysUser> sysUsers = sysUserMapper.selectAll(userPageReqVO);
        //查询全部有效菜单
        List<SysPermission> sysPermissions = permissionMapper.selectAll(null);
        return sysPermissions;
    }*/

    //找到所有超管的菜单 ,只查系统菜单下的
    private List<SysPermission> getSuperPerms() {
        List<SysPermission> permissions = new ArrayList<>();
        //超管,只查询 系统管理下 的菜单
        //SysPermission sysManageMenu = permissionService.findSysManageMenu();
        SysPermission sysPermissionQuery = new SysPermission();
        //sysPermissionQuery.setName(CommonConstant.SYS_MENU_NAME);
        //sysPermissionQuery.setPid(CommonConstant.TOP_PARENT_ID);
        sysPermissionQuery.setId(CommonConstant.SYS_MENU_Id);
        SysPermission sysManageMenu = permissionMapper.selectOneByCondition(sysPermissionQuery);
        if (sysManageMenu != null) {
            List<SysPermission> list = new ArrayList<>();
            list.add(sysManageMenu);
            List<Integer> queryIds = new ArrayList<>();
            queryIds.add(sysManageMenu.getId());

            //permissions = permissionService.getSysMangeMenus(list, queryIds);
            permissions = getSysMangeMenus(list, queryIds);
        }
        return permissions;
    }

    public List<SysPermission> getSysMangeMenus(List<SysPermission> list, List<Integer> queryIds) {
        if (queryIds == null || queryIds.isEmpty()) {
            return list;
        }
        //查询父id在queryIds中的
        List<SysPermission> sysPermissions = permissionMapper.selectChilds(queryIds);
        List<Integer> ids = new ArrayList<>();
        list.addAll(sysPermissions);
        //将ids作为下一次循环的入参
        for (SysPermission sysPermission : sysPermissions) {
            ids.add(sysPermission.getId());
        }
        return getSysMangeMenus(list, ids);
    }


    private List<String> dealPowerTag(List<SysPermission> permissions) {
        final List<String> powerList = new ArrayList<>();
        permissions.stream().filter(p -> !StrUtil.isBlank(p.getPerms())).forEach(p -> {
            powerList.add(p.getPerms());
        });
        return powerList;
    }
}
