// JWT 토큰 무효화 서비스
// user_info.token_version 기반으로 기존 JWT 토큰을 무효화

import { query } from "../database/db";
import { cache } from "../utils/cache";
import { logger } from "../utils/logger";

const TOKEN_VERSION_CACHE_TTL = 2 * 60 * 1000; // 2분 캐시

export class TokenInvalidationService {
  /**
   * 캐시 키 생성
   */
  static cacheKey(userId: string): string {
    return `token_version:${userId}`;
  }

  /**
   * 단일 사용자의 토큰 무효화 (token_version +1)
   */
  static async invalidateUserTokens(userId: string): Promise<void> {
    try {
      await query(
        `UPDATE user_info SET token_version = COALESCE(token_version, 0) + 1 WHERE user_id = $1`,
        [userId]
      );
      cache.delete(this.cacheKey(userId));
      logger.info(`토큰 무효화: ${userId}`);
    } catch (error) {
      logger.error(`토큰 무효화 실패: ${userId}`, { error });
    }
  }

  /**
   * 여러 사용자의 토큰 일괄 무효화
   */
  static async invalidateMultipleUserTokens(userIds: string[]): Promise<void> {
    if (userIds.length === 0) return;
    try {
      const placeholders = userIds.map((_, i) => `$${i + 1}`).join(", ");
      await query(
        `UPDATE user_info SET token_version = COALESCE(token_version, 0) + 1 WHERE user_id IN (${placeholders})`,
        userIds
      );
      userIds.forEach((id) => cache.delete(this.cacheKey(id)));
      logger.info(`토큰 일괄 무효화: ${userIds.length}명`);
    } catch (error) {
      logger.error(`토큰 일괄 무효화 실패`, { error, userIds });
    }
  }

  /**
   * 현재 token_version 조회 (캐시 사용)
   */
  static async getUserTokenVersion(userId: string): Promise<number> {
    const cacheKey = this.cacheKey(userId);
    const cached = cache.get<number>(cacheKey);
    if (cached !== null) {
      return cached;
    }

    try {
      const result = await query<{ token_version: number | null }>(
        `SELECT token_version FROM user_info WHERE user_id = $1`,
        [userId]
      );
      const version = result.length > 0 ? (result[0].token_version ?? 0) : 0;
      cache.set(cacheKey, version, TOKEN_VERSION_CACHE_TTL);
      return version;
    } catch (error) {
      logger.error(`token_version 조회 실패: ${userId}`, { error });
      return 0;
    }
  }
}
