<?php

namespace App\Services\Auth;

use App\Models\Auth\User;
use Illuminate\Support\Facades\Cache;

class UserOnlineService
{
    protected $cachePrefix = 'user_online:';
    protected $expireMinutes = 5;

    /**
     * 设置用户在线
     */
    public function setOnline(int $userId, string $token): void
    {
        $key = $this->getCacheKey($userId, $token);
        Cache::put($key, [
            'user_id' => $userId,
            'token' => $token,
            'last_active_at' => now()->toDateTimeString(),
            'ip' => request()->ip(),
            'user_agent' => request()->userAgent(),
        ], now()->addMinutes($this->expireMinutes));

        // 更新用户的最后在线时间
        User::where('id', $userId)->update([
            'last_active_at' => now(),
        ]);
    }

    /**
     * 更新用户在线状态
     */
    public function updateOnline(int $userId, string $token): void
    {
        $key = $this->getCacheKey($userId, $token);
        if (Cache::has($key)) {
            Cache::put($key, [
                'user_id' => $userId,
                'token' => $token,
                'last_active_at' => now()->toDateTimeString(),
                'ip' => request()->ip(),
                'user_agent' => request()->userAgent(),
            ], now()->addMinutes($this->expireMinutes));
        }
    }

    /**
     * 设置用户离线
     */
    public function setOffline(int $userId, string $token): void
    {
        $key = $this->getCacheKey($userId, $token);
        Cache::forget($key);
    }

    /**
     * 设置用户所有设备离线
     */
    public function setAllOffline(int $userId): void
    {
        $pattern = $this->cachePrefix . $userId . ':*';
        $keys = Cache::store('redis')->getPrefix() . $pattern;

        // Redis 模式删除
        if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
            $redis = Cache::getStore()->connection();
            $keys = $redis->keys($this->cachePrefix . $userId . ':*');
            if (!empty($keys)) {
                $redis->del($keys);
            }
        }
    }

    /**
     * 检查用户是否在线
     */
    public function isOnline(int $userId): bool
    {
        $pattern = $this->cachePrefix . $userId . ':*';

        if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
            $redis = Cache::getStore()->connection();
            $keys = $redis->keys($this->cachePrefix . $userId . ':*');
            return !empty($keys);
        }

        return false;
    }

    /**
     * 获取用户在线信息
     */
    public function getOnlineInfo(int $userId, string $token): ?array
    {
        $key = $this->getCacheKey($userId, $token);
        return Cache::get($key);
    }

    /**
     * 获取用户所有在线会话
     */
    public function getUserSessions(int $userId): array
    {
        $sessions = [];

        if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
            $redis = Cache::getStore()->connection();
            $keys = $redis->keys($this->cachePrefix . $userId . ':*');

            foreach ($keys as $key) {
                $session = $redis->get($key);
                if ($session) {
                    $sessions[] = json_decode($session, true);
                }
            }
        }

        return $sessions;
    }

    /**
     * 获取所有在线用户数量
     */
    public function getOnlineCount(): int
    {
        $count = 0;

        if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
            $redis = Cache::getStore()->connection();
            $keys = $redis->keys($this->cachePrefix . '*');
            // 去重用户ID
            $userIds = [];
            foreach ($keys as $key) {
                preg_match('/user_online:(\d+):/', $key, $matches);
                if (isset($matches[1])) {
                    $userIds[$matches[1]] = true;
                }
            }
            $count = count($userIds);
        }

        return $count;
    }

    /**
     * 获取在线用户列表
     */
    public function getOnlineUsers(int $limit = 100): array
    {
        $onlineUsers = [];

        if (Cache::getStore() instanceof \Illuminate\Cache\RedisStore) {
            $redis = Cache::getStore()->connection();
            $keys = $redis->keys($this->cachePrefix . '*');

            $userIds = [];
            $userSessions = [];

            foreach ($keys as $key) {
                $session = $redis->get($key);
                if ($session) {
                    $session = json_decode($session, true);
                    $userId = $session['user_id'];
                    if (!isset($userIds[$userId])) {
                        $userIds[$userId] = $userId;
                    }
                    $userSessions[$userId] = $session;
                }
            }

            $userIdList = array_values(array_slice($userIds, 0, $limit));
            $users = User::whereIn('id', $userIdList)->get();

            foreach ($users as $user) {
                $onlineUsers[] = [
                    'id' => $user->id,
                    'username' => $user->username,
                    'real_name' => $user->real_name,
                    'avatar' => $user->avatar,
                    'last_active_at' => $userSessions[$user->id]['last_active_at'] ?? null,
                    'ip' => $userSessions[$user->id]['ip'] ?? null,
                ];
            }
        }

        return $onlineUsers;
    }

    /**
     * 清理过期会话
     */
    public function cleanExpiredSessions(): int
    {
        // Redis 的 TTL 会自动清理过期键
        return 0;
    }

    /**
     * 生成缓存键
     */
    protected function getCacheKey(int $userId, string $token): string
    {
        return $this->cachePrefix . $userId . ':' . md5($token);
    }
}
