// HTTP 客户端封装 — 带 Token 自动刷新拦截器

import type { AuthResponse } from '@/types/session';

const API_BASE_URL = import.meta.env.VITE_API_URL || '/api/v1';

/** localStorage key 前缀 */
const LS_TOKEN_KEY = 'token';
const LS_REFRESH_TOKEN_KEY = 'refresh_token';
const LS_USER_ID_KEY = 'user_id';

// ========== Token 刷新队列（避免多个并发请求同时刷新 token） ==========

let isRefreshing = false;
let refreshPromise: Promise<string | null> | null = null;

/**
 * 等待中的请求队列。当 token 刷新完成后，用新 token 重放这些请求。
 */
type QueuedRequest = {
  resolve: (token: string | null) => void;
  reject: (err: unknown) => void;
};
let refreshQueue: QueuedRequest[] = [];

function onRefreshDone(newToken: string | null) {
  for (const q of refreshQueue) {
    q.resolve(newToken);
  }
  refreshQueue = [];
}

function onRefreshFailed(err: unknown) {
  for (const q of refreshQueue) {
    q.reject(err);
  }
  refreshQueue = [];
}

// ========== 存储辅助函数 ==========

/** 存储认证令牌 */
export function setToken(token: string) {
  try {
    localStorage.setItem(LS_TOKEN_KEY, token);
  } catch { /* ignore */ }
}

/** 获取认证令牌 */
export function getToken(): string | null {
  try {
    return localStorage.getItem(LS_TOKEN_KEY);
  } catch {
    return null;
  }
}

/** 获取刷新令牌 */
export function getRefreshToken(): string | null {
  try {
    return localStorage.getItem(LS_REFRESH_TOKEN_KEY);
  } catch {
    return null;
  }
}

/** 存储 tokens */
export function setTokens(accessToken: string, refreshTokenValue?: string) {
  setToken(accessToken);
  if (refreshTokenValue) {
    try {
      localStorage.setItem(LS_REFRESH_TOKEN_KEY, refreshTokenValue);
    } catch { /* ignore */ }
  }
}

/** 清除认证令牌 */
export function clearToken() {
  try {
    localStorage.removeItem(LS_TOKEN_KEY);
    localStorage.removeItem(LS_REFRESH_TOKEN_KEY);
    localStorage.removeItem(LS_USER_ID_KEY);
  } catch { /* ignore */ }
}

/** 检查是否已认证 */
export function isAuthenticated(): boolean {
  return !!getToken();
}

// ========== Token 刷新逻辑 ==========

/**
 * 尝试刷新 token。如果已经有正在进行的刷新请求，等待它完成。
 */
async function tryRefreshToken(): Promise<string | null> {
  const refreshTokenValue = getRefreshToken();
  if (!refreshTokenValue) {
    // 没有 refresh token，无法刷新
    return null;
  }

  // 如果已经有刷新正在进行中，加入队列等待
  if (isRefreshing && refreshPromise) {
    return new Promise((resolve, reject) => {
      refreshQueue.push({ resolve, reject });
    });
  }

  isRefreshing = true;
  refreshPromise = (async () => {
    try {
      const response = await fetch(`${API_BASE_URL}/auth/refresh`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${refreshTokenValue}`,
        },
        body: JSON.stringify({ refresh_token: refreshTokenValue }),
      });

      if (!response.ok) {
        throw new Error(`Refresh failed: ${response.status}`);
      }

      const data: AuthResponse = await response.json();
      if (data.token) {
        setTokens(data.token, data.refresh_token);
        return data.token;
      }
      return null;
    } catch {
      // 刷新失败
      clearToken();
      return null;
    } finally {
      isRefreshing = false;
      refreshPromise = null;
    }
  })();

  try {
    const newToken = await refreshPromise;
    onRefreshDone(newToken);
    return newToken;
  } catch (err) {
    onRefreshFailed(err);
    return null;
  }
}

/** 请求选项 */
interface RequestOptions {
  method?: string;
  body?: unknown;
  headers?: Record<string, string>;
  auth?: boolean;
}

/** API 响应格式 */
interface ApiResponse<T = unknown> {
  data?: T;
  error?: string;
  status: number;
}

/**
 * 发送 API 请求，内置 401 自动刷新拦截
 */
async function request<T = unknown>(endpoint: string, options: RequestOptions = {}): Promise<ApiResponse<T>> {
  const { method = 'GET', body, auth = true } = options;

  const makeRequest = async (tokenOverride?: string): Promise<ApiResponse<T>> => {
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
      ...options.headers,
    };

    const token = tokenOverride || (auth ? getToken() : null);
    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }

    try {
      const response = await fetch(`${API_BASE_URL}${endpoint}`, {
        method,
        headers,
        body: body ? JSON.stringify(body) : undefined,
      });

      // 401 且当前请求需要认证、且不是 refresh 接口本身、且尚未重试
      if (response.status === 401 && auth && endpoint !== '/auth/refresh' && !tokenOverride) {
        const newToken = await tryRefreshToken();
        if (newToken) {
          // 用新 token 重试
          return makeRequest(newToken);
        }
        // 刷新失败，清除状态，跳转登录页
        clearToken();
        // 触发页面重新加载以显示登录页
        if (typeof window !== 'undefined') {
          window.location.href = '/login';
        }
        return {
          error: '认证已过期，请重新登录',
          status: 401,
        };
      }

      const data = await response.json().catch(() => null);

      if (!response.ok) {
        return {
          error: data?.error || `请求失败 (${response.status})`,
          status: response.status,
        };
      }

      return { data: data as T, status: response.status };
    } catch (err) {
      return {
        error: err instanceof Error ? err.message : '网络错误',
        status: 0,
      };
    }
  };

  return makeRequest();
}

// ========== 认证 API ==========

export async function login(username: string, password: string): Promise<ApiResponse<AuthResponse>> {
  const resp = await request<AuthResponse>('/auth/login', {
    method: 'POST',
    body: { username, password },
    auth: false,
  });
  if (resp.data?.token) {
    setTokens(resp.data.token, resp.data.refresh_token);
    localStorage.setItem(LS_USER_ID_KEY, resp.data.user_id);
  }
  return resp;
}

export async function register(username: string, password: string, email: string, nickname: string, verifyCode: string): Promise<ApiResponse<AuthResponse>> {
  const resp = await request<AuthResponse>('/auth/register', {
    method: 'POST',
    body: { username, password, email, nickname, verify_code: verifyCode },
    auth: false,
  });
  if (resp.data?.token) {
    setTokens(resp.data.token, resp.data.refresh_token);
    localStorage.setItem(LS_USER_ID_KEY, resp.data.user_id);
  }
  return resp;
}

export async function refreshToken(): Promise<ApiResponse<AuthResponse>> {
  const resp = await request<AuthResponse>('/auth/refresh', { method: 'POST' });
  if (resp.data?.token) {
    setTokens(resp.data.token, resp.data.refresh_token);
  }
  return resp;
}

// ========== 会话 API ==========

export async function createSession(title?: string) {
  return request('/sessions', { method: 'POST', body: { title } });
}

export async function listSessions() {
  return request('/sessions');
}

export async function getSession(id: string) {
  return request(`/sessions/${id}`);
}

export async function deleteSession(id: string) {
  return request(`/sessions/${id}`, { method: 'DELETE' });
}

export async function fetchSessionMessages(id: string) {
  return request(`/sessions/${id}/messages`);
}

// ========== 记忆 API ==========

export async function searchMemory(query: string) {
  return request(`/memory/search?q=${encodeURIComponent(query)}`);
}

export async function listMemories() {
  return request('/memory');
}

export async function addMemory(content: string, category?: string, priority?: number) {
  return request('/memory', { method: 'POST', body: { content, category, priority } });
}

export async function deleteMemory(id: string) {
  return request(`/memory?id=${encodeURIComponent(id)}`, { method: 'DELETE' });
}

export { request, type ApiResponse };
