/**
 * 认证中间件
 * 通过外部 API 验证 Token
 */

import fetch from 'node-fetch';
import { prisma } from '../db/client.js';

// 是否禁用认证（开发/测试模式）
const AUTH_DISABLED = process.env.AUTH_DISABLED === 'true' || process.env.NODE_ENV === 'test';

// 默认认证 API URL
const DEFAULT_AUTH_CHECK_URL = 'https://sxwz.xueai.art/api/auth/check/checkTokenRn';

// Token 缓存（减少外部 API 调用）
const tokenCache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 分钟

// 测试用户（认证禁用时使用）
const TEST_USER = {
  id: 'test-user-001',
  username: 'testuser',
  nickname: '测试用户'
};

/**
 * 验证 Token
 * @param {string} token - JWT Token
 * @returns {Promise<Object|null>} 用户信息或 null
 */
export async function verifyToken(token) {
  if (!token) return null;

  // 1. 检查缓存
  const cached = tokenCache.get(token);
  if (cached && cached.expiresAt > Date.now()) {
    return cached.user;
  }

  // 2. 调用外部 API 验证
  const authCheckUrl = process.env.AUTH_CHECK_URL || DEFAULT_AUTH_CHECK_URL;
  const checkUrl = `${authCheckUrl}/${token}`;

  try {
    const response = await fetch(checkUrl, {
      method: 'GET',
      headers: {
        'Accept': 'application/json',
        'User-Agent': 'PaperBurner-LocalProxy/1.0'
      },
      signal: AbortSignal.timeout(5000) // 5 秒超时
    });

    if (!response.ok) {
      console.warn('[Auth] Token verification failed:', response.status);
      return null;
    }

    const data = await response.json();

    // 检查响应格式
    if (data.code !== '0' && data.success !== true) {
      console.warn('[Auth] Token verification returned error:', data.msg || data.message);
      return null;
    }

    const user = data.data;
    if (!user || !user.id) {
      console.warn('[Auth] Invalid user data in response');
      return null;
    }

    // 3. 缓存结果
    tokenCache.set(token, {
      user: {
        id: String(user.id),
        username: user.username,
        nickname: user.nickname || user.username
      },
      expiresAt: Date.now() + CACHE_TTL
    });

    return user;

  } catch (error) {
    console.error('[Auth] Token verification error:', error.message);
    return null;
  }
}

/**
 * 确保用户存在（首次访问时自动创建）
 * @param {string} userId - 用户 ID
 * @param {string} name - 用户名称
 */
export async function ensureUserExists(userId, name) {
  try {
    await prisma.user.upsert({
      where: { id: userId },
      update: {}, // 不更新任何字段
      create: {
        id: userId,
        name: name || `用户${userId.slice(-6)}`
      }
    });
  } catch (error) {
    console.error('[Auth] Failed to ensure user exists:', error.message);
  }
}

/**
 * 认证中间件
 * 验证 Token 并自动创建用户
 */
export async function requireAuth(req, res, next) {
  // 认证禁用模式（开发/测试）
  if (AUTH_DISABLED) {
    await ensureUserExists(TEST_USER.id, TEST_USER.nickname);
    req.user = TEST_USER;
    if (typeof next === 'function') {
      next();
    }
    return;
  }

  const authHeader = req.headers.authorization;
  const token = authHeader?.split(' ')[1];

  if (!token) {
    res.writeHead(401, {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': req.headers.origin || '*'
    });
    res.end(JSON.stringify({ error: 'Token required' }));
    return;
  }

  const user = await verifyToken(token);

  if (!user) {
    res.writeHead(401, {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': req.headers.origin || '*'
    });
    res.end(JSON.stringify({ error: 'Invalid or expired token' }));
    return;
  }

  // 自动创建用户（首次访问）
  await ensureUserExists(user.id, user.nickname || user.username);

  // 将用户信息附加到请求对象
  req.user = user;

  // 调用下一个处理器
  if (typeof next === 'function') {
    next();
  }
}

/**
 * 可选认证中间件
 * 如果有 Token 则验证，没有则跳过
 */
export async function optionalAuth(req, res, next) {
  const authHeader = req.headers.authorization;
  const token = authHeader?.split(' ')[1];

  if (token) {
    const user = await verifyToken(token);
    if (user) {
      await ensureUserExists(user.id, user.nickname || user.username);
      req.user = user;
    }
  }

  if (typeof next === 'function') {
    next();
  }
}

/**
 * 清理过期的 Token 缓存
 */
export function cleanupTokenCache() {
  const now = Date.now();
  for (const [token, data] of tokenCache.entries()) {
    if (data.expiresAt < now) {
      tokenCache.delete(token);
    }
  }
}

// 每 10 分钟清理一次缓存
setInterval(cleanupTokenCache, 10 * 60 * 1000);

export default {
  verifyToken,
  ensureUserExists,
  requireAuth,
  optionalAuth
};