package com.chushang.system.service;

import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.system.SystemUtil;
import com.chushang.common.core.constant.CacheConstants;
import com.chushang.common.core.util.IPUtils;
import com.chushang.common.core.util.StringUtils;
import com.chushang.common.mybatis.page.CommonParam;
import com.chushang.common.mybatis.utils.PageClass;
import com.chushang.common.mybatis.utils.PageResult;
import com.chushang.security.auth.AuthUtil;
import com.chushang.security.entity.vo.LoginUser;
import com.chushang.security.service.TokenService;
import com.chushang.system.entity.vo.SysUserOnline;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 在线用户 服务层
 *
 * @author ruoyi
 */
@Slf4j
@Service
public class ISysUserOnlineService
{

    @Resource
    RedissonClient redissonClient;
    @Resource
    TokenService tokenService;

    public PageResult selectOnlineByIpaddr(String ipaddr, String userName, CommonParam commonParam){
        Collection<String> keys = new ArrayList<>();
        redissonClient.getKeys().getKeys().forEach(key-> {
            if (key.startsWith(CacheConstants.LOGIN_TOKEN_KEY)){
                keys.add(key);
            }
        });
        List<SysUserOnline> userOnlineList = new ArrayList<>();
        for (String key : keys)
        {
            RBucket<LoginUser> bucket = redissonClient.getBucket(key);
            if (!bucket.isExists()){
                continue;
            }
            LoginUser user = bucket.get();
            if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
            {
                userOnlineList.add(selectOnlineByInfo(ipaddr, userName, user));
            }
            else if (StringUtils.isNotEmpty(ipaddr))
            {
                userOnlineList.add(selectOnlineByIpaddr(ipaddr, user));
            }
            else if (StringUtils.isNotEmpty(userName))
            {
                userOnlineList.add(selectOnlineByUserName(userName, user));
            }
            else
            {
                userOnlineList.add(loginUserToUserOnline(user));
            }
        }
        Collections.reverse(userOnlineList);
        userOnlineList.removeAll(Collections.singleton(null));
        List<SysUserOnline> userOnlines = new PageClass<SysUserOnline>()
                .page(commonParam.getPage(), commonParam.getLimit(), userOnlineList);
        return new PageResult(userOnlines, userOnlineList.size(), commonParam.getLimit(), commonParam.getPage());
    }

    /**
     * 通过登录地址查询信息
     *
     * @param ipaddr 登录地址
     * @param user 用户信息
     * @return 在线用户信息
     */
    public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user)
    {
        if (StringUtils.equals(ipaddr, user.getIpaddr()))
        {
            return loginUserToUserOnline(user);
        }
        return null;
    }

    /**
     * 通过用户名称查询信息
     *
     * @param userName 用户名称
     * @param user 用户信息
     * @return 在线用户信息
     */
    public SysUserOnline selectOnlineByUserName(String userName, LoginUser user)
    {
        if (StringUtils.equals(userName, user.getUsername()))
        {
            return loginUserToUserOnline(user);
        }
        return null;
    }

    /**
     * 通过登录地址/用户名称查询信息
     *
     * @param ipaddr 登录地址
     * @param userName 用户名称
     * @param user 用户信息
     * @return 在线用户信息
     */
    public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user)
    {
        if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
        {
            return loginUserToUserOnline(user);
        }
        return null;
    }

    /**
     * 设置在线用户信息
     *
     * @param user 用户信息
     * @return 在线用户
     */
    public SysUserOnline loginUserToUserOnline(LoginUser user)
    {
        if (StringUtils.isNull(user))
        {
            return null;
        }
        SysUserOnline sysUserOnline = new SysUserOnline();
        sysUserOnline.setTokenId(user.getToken());
        sysUserOnline.setUserName(user.getUsername());
        sysUserOnline.setIpaddr(user.getIpaddr());
        sysUserOnline.setLoginTime(user.getLoginTime());
        sysUserOnline.setLoginLocation(IPUtils.getLocalCityInfo(user.getIpaddr()));
        sysUserOnline.setBrowser(IPUtils.getBrowser());
        sysUserOnline.setOs(IPUtils.osName());
        return sysUserOnline;
    }

    public void forceLogout(String tokenId) {
        tokenService.forcedRetreatByTokenKey(tokenId);
    }
}
