import { API_BASE_URL } from '../utils/constants';

interface ApiResponse<T = any> {
  data: T;
  status: number;
}

class ApiClient {
  private baseURL: string;

  constructor(baseURL: string) {
    this.baseURL = baseURL;
  }

  private getAuthHeaders(): Record<string, string> {
    // V2 API key auth (primary)
    const apiKey = localStorage.getItem('kb_api_key');
    const activeTenantId = localStorage.getItem('kb_active_tenant_id');
    // Legacy JWT token (fallback, kept for compatibility during transition)
    const token = localStorage.getItem('authToken') || localStorage.getItem('token');
    const language = localStorage.getItem('userLanguage') || 'ja';
    return {
      'Content-Type': 'application/json',
      'x-user-language': language,
      ...(apiKey && { 'x-api-key': apiKey }),
      ...(activeTenantId && { 'x-tenant-id': activeTenantId }),
      ...(token && { Authorization: `Bearer ${token}` }),
    };
  }

  private async handleResponse<T>(response: Response): Promise<ApiResponse<T>> {
    const text = await response.text();
    let data: any;
    try {
      data = text ? JSON.parse(text) : null;
    } catch (e) {
      data = null;
    }

    if (!response.ok) {
      throw new Error(data?.message || text || 'Request failed');
    }

    return { data: data as T, status: response.status };
  }

  // 新しい API 呼び出し方法、{ data, status } を返す
  async get<T = any>(url: string): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseURL}${url}`, {
      method: 'GET',
      headers: this.getAuthHeaders(),
    });

    return this.handleResponse<T>(response);
  }

  async post<T = any>(url: string, body?: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseURL}${url}`, {
      method: 'POST',
      headers: this.getAuthHeaders(),
      body: body ? JSON.stringify(body) : undefined,
    });

    return this.handleResponse<T>(response);
  }

  async put<T = any>(url: string, body?: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseURL}${url}`, {
      method: 'PUT',
      headers: this.getAuthHeaders(),
      body: body ? JSON.stringify(body) : undefined,
    });

    return this.handleResponse<T>(response);
  }

  async patch<T = any>(url: string, body?: any): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseURL}${url}`, {
      method: 'PATCH',
      headers: this.getAuthHeaders(),
      body: body ? JSON.stringify(body) : undefined,
    });

    return this.handleResponse<T>(response);
  }

  async delete<T = any>(url: string): Promise<ApiResponse<T>> {
    const response = await fetch(`${this.baseURL}${url}`, {
      method: 'DELETE',
      headers: this.getAuthHeaders(),
    });

    return this.handleResponse<T>(response);
  }
  
  // New methods for special formats
  async getBlob(url: string): Promise<Blob> {
    const response = await fetch(`${this.baseURL}${url}`, {
      method: 'GET',
      headers: this.getAuthHeaders(),
    });

    if (!response.ok) {
      throw new Error('Request failed');
    }

    return await response.blob();
  }

  async postMultipart<T = any>(url: string, formData: FormData): Promise<ApiResponse<T>> {
    const headers = this.getAuthHeaders();
    // Remove Content-Type to let the browser set it with the correct boundary
    delete headers['Content-Type'];

    const response = await fetch(`${this.baseURL}${url}`, {
      method: 'POST',
      headers,
      body: formData,
    });

    return this.handleResponse<T>(response);
  }
  
  // Legacy compatibility method — returns raw Response for streaming and other special cases
  async request(path: string, options: RequestInit = {}): Promise<Response> {
    const apiKey = localStorage.getItem('kb_api_key');
    const activeTenantId = localStorage.getItem('kb_active_tenant_id');
    const token = localStorage.getItem('authToken');
    const headers = new Headers(options.headers);

    if (apiKey) headers.set('x-api-key', apiKey);
    if (activeTenantId) headers.set('x-tenant-id', activeTenantId);
    if (token) headers.set('Authorization', `Bearer ${token}`);

    const language = localStorage.getItem('userLanguage') || 'ja';
    headers.set('x-user-language', language);

    let url = path;
    if (!path.startsWith('http')) {
      const cleanPath = path.startsWith('/') ? path : `/${path}`;
      url = `${this.baseURL}${cleanPath}`;
    }

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

    if (response.status === 401) {
      localStorage.removeItem('kb_api_key');
      localStorage.removeItem('authToken');
      window.location.href = '/login';
      throw new Error('Unauthorized');
    }

    return response;
  }
}

export const apiClient = new ApiClient(API_BASE_URL);