/**
 * HTTP 客户端封装
 * 统一处理请求/响应拦截、错误处理、Token 管理
 */

import { API_BASE_URL } from '../config/env';
import type { ApiResponse } from '../types/api';

// Token 存储键名
const TOKEN_KEY = 'texpixel_token';
const TOKEN_EXPIRES_KEY = 'texpixel_token_expires';
const USER_EMAIL_KEY = 'texpixel_user_email';

/**
 * Token 管理工具
 */
export const tokenManager = {
  getToken(): string | null {
    return localStorage.getItem(TOKEN_KEY);
  },

  setToken(token: string, expiresAt: number, email?: string): void {
    localStorage.setItem(TOKEN_KEY, token);
    localStorage.setItem(TOKEN_EXPIRES_KEY, expiresAt.toString());
    if (email) {
      localStorage.setItem(USER_EMAIL_KEY, email);
    }
  },

  removeToken(): void {
    localStorage.removeItem(TOKEN_KEY);
    localStorage.removeItem(TOKEN_EXPIRES_KEY);
    localStorage.removeItem(USER_EMAIL_KEY);
  },

  getEmail(): string | null {
    return localStorage.getItem(USER_EMAIL_KEY);
  },

  isTokenValid(): boolean {
    const token = this.getToken();
    const expiresAt = localStorage.getItem(TOKEN_EXPIRES_KEY);

    if (!token || !expiresAt) return false;

    // 提前 5 分钟判定为过期
    const expiresTimestamp = parseInt(expiresAt, 10) * 1000;
    return Date.now() < expiresTimestamp - 5 * 60 * 1000;
  },

  getExpiresAt(): number | null {
    const expiresAt = localStorage.getItem(TOKEN_EXPIRES_KEY);
    return expiresAt ? parseInt(expiresAt, 10) : null;
  },
};

/**
 * 自定义 API 错误类
 */
export class ApiError extends Error {
  constructor(
    public code: number,
    message: string,
    public requestId?: string
  ) {
    super(message);
    this.name = 'ApiError';
  }
}

/**
 * 请求配置类型
 */
interface RequestConfig extends RequestInit {
  skipAuth?: boolean;
}

/**
 * 发起 HTTP 请求
 */
async function request<T>(
  endpoint: string,
  config: RequestConfig = {}
): Promise<ApiResponse<T>> {
  const { skipAuth = false, headers: customHeaders, ...restConfig } = config;

  const headers: HeadersInit = {
    'Content-Type': 'application/json',
    ...customHeaders,
  };

  // 自动添加 Authorization header
  if (!skipAuth) {
    const token = tokenManager.getToken();
    if (token) {
      (headers as Record<string, string>)['Authorization'] = token;
    }
  }

  const url = `${API_BASE_URL}${endpoint}`;

  try {
    const response = await fetch(url, {
      ...restConfig,
      headers,
    });

    const data: ApiResponse<T> = await response.json();

    // 统一处理业务错误
    if (data.code !== 200) {
      throw new ApiError(data.code, data.message, data.request_id);
    }

    return data;
  } catch (error) {
    if (error instanceof ApiError) {
      throw error;
    }

    // 网络错误或其他错误
    throw new ApiError(-1, '网络错误，请检查网络连接');
  }
}

/**
 * HTTP 方法快捷函数
 */
export const http = {
  get<T>(endpoint: string, config?: RequestConfig): Promise<ApiResponse<T>> {
    return request<T>(endpoint, { ...config, method: 'GET' });
  },

  post<T>(endpoint: string, body?: unknown, config?: RequestConfig): Promise<ApiResponse<T>> {
    return request<T>(endpoint, {
      ...config,
      method: 'POST',
      body: body ? JSON.stringify(body) : undefined,
    });
  },

  put<T>(endpoint: string, body?: unknown, config?: RequestConfig): Promise<ApiResponse<T>> {
    return request<T>(endpoint, {
      ...config,
      method: 'PUT',
      body: body ? JSON.stringify(body) : undefined,
    });
  },

  delete<T>(endpoint: string, config?: RequestConfig): Promise<ApiResponse<T>> {
    return request<T>(endpoint, { ...config, method: 'DELETE' });
  },
};

export default http;

