type RequestOptions = {
    method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
    headers?: Record<string, string>;
    body?: unknown;
    queryParams?: Record<string, string | number>;
};
  
type Interceptor = {
    request?: (config: RequestInit) => RequestInit;
    requestError?: (error: unknown) => Promise<never>; // 错误拦截器应始终抛出
    response?: (response: Response) => Response | Promise<Response>;
    // 错误拦截器必须抛出或返回与请求相同类型的结果
    responseError?: <T>(error: unknown) => Promise<T>;
};
  
export class HttpClient {
    private static instance: HttpClient;
    private baseUrl: string;
    private interceptors: Interceptor[] = [];
  
    private constructor(baseUrl: string) {
      this.baseUrl = baseUrl;
    }
  
    public static getInstance(baseUrl: string): HttpClient {
      if (!HttpClient.instance) {
        HttpClient.instance = new HttpClient(baseUrl);
      }
      return HttpClient.instance;
    }
  
    // 添加拦截器
    addInterceptor(interceptor: Interceptor) {
      this.interceptors.push(interceptor);
      return this; // 支持链式调用
    }
  
    async request<T>(endpoint: string, options: RequestOptions = {}): Promise<T> {
      const { 
        method = 'GET', 
        headers = {}, 
        body, 
        queryParams = {} 
      } = options;
  
      const url = new URL(`${this.baseUrl}${endpoint}`);
      Object.entries(queryParams).forEach(([key, value]) => {
        url.searchParams.append(key, String(value));
      });
  
      let config: RequestInit = {
        method,
        headers: {
          'Content-Type': 'application/json',
          ...headers
        }
      };
  
      if (body) {
        config.body = JSON.stringify(body);
      }
  
      // 请求拦截器处理
      for (const interceptor of this.interceptors) {
        if (interceptor.request) {
          config = interceptor.request(config);
        }
      }
  
      try {
        let response = await fetch(url.toString(), config);
        
        // 响应拦截器处理
        for (const interceptor of this.interceptors) {
          if (interceptor.response) {
            response = await interceptor.response(response);
          }
        }
  
        if (!response.ok) {
          const errorData = await response.json();
          throw new Error(`HTTP error! Status: ${response.status}, Message: ${errorData.message || 'Unknown error'}`);
        }
  
        return await response.json();
      } catch (error) {
        // 改进的错误拦截器处理
        let lastError = error;
        
        for (const interceptor of this.interceptors) {
          if (interceptor.responseError) {
            try {
              // 错误拦截器必须返回Promise<T>或抛出
              return await interceptor.responseError<T>(lastError);
            } catch (e) {
              // 保存最新错误并继续下一个拦截器
              lastError = e;
              console.error('Interceptor error:', e);
            }
          }
        }
        
        // 如果所有拦截器都未能处理错误，则抛出最后一个错误
        throw lastError;
      }
    }
    get<T>(endpoint: string, queryParams?: Record<string, string | number>) {
      return this.request<T>(endpoint, { queryParams });
    }
  
    post<T>(endpoint: string, body?: unknown, headers?: Record<string, string>) {
      return this.request<T>(endpoint, { method: 'POST', body, headers });
    }
  
    put<T>(endpoint: string, body?: unknown, headers?: Record<string, string>) {
      return this.request<T>(endpoint, { method: 'PUT', body, headers });
    }
  
    delete<T>(endpoint: string, headers?: Record<string, string>) {
      return this.request<T>(endpoint, { method: 'DELETE', headers });
    }
}
  
const client = HttpClient.getInstance('http://localhost:8080/');
// 添加Token注入拦截器
client.addInterceptor({
    request: (config) => {
      const token = localStorage.getItem('token'); // 从存储中获取token
      if (token) {
        config.headers = {
          ...config.headers,
          'Authorization': `Bearer ${token}`
        };
      }
      return config;
    },
    responseError: async (error) => {
        if (error instanceof Error && error.message.includes('401')) {
          console.log('Token expired, redirecting to login...');
          // 示例：重定向到登录页
          window.location.href = '/login';
          // 必须返回Promise<never>或抛出
          return new Promise(() => {}); // 永远不解决的Promise
        }
        throw error;
      }
});
export default client as HttpClient;