import { getCSRFToken } from '@/services/token.js';

class APIClient {
  constructor() {
    this.globals = {};
    this.abortController = null;
    this.contextPath = document.querySelector('meta[name="context-path"]')?.getAttribute('content') || '/';
    this.contextPath = this.contextPath.endsWith('/') ? this.contextPath : this.contextPath + '/';
    this.CLIENT_URL = 'mgmt/api/test.do';
  }

  abort() {
    if (this.abortController) {
      this.abortController.abort();
      this.abortController = null;
    }
  }

  async sendAPIRequest(model, onLog = () => {}) {
    try {
      onLog(`Request: ${model.method} ${model.path}`);

      const response = await this.makeRequest(model);
      const formattedResponse = this.formatResponse(response);
      return formattedResponse;
    } catch (error) {
      if (error.name === 'AbortError') {
        throw new Error('Request was cancelled');
      }
      throw new Error(`API Error: ${error.message}`);
    } finally {
      this.abortController = null;
    }
  }

  async makeRequest(request) {
    this.abortController = new AbortController();

    const response = await fetch(this.getClientUrl(), {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-XSRF-TOKEN': getCSRFToken()
      },
      body: JSON.stringify(request),
      signal: this.abortController.signal
    });

    if (!response.ok) {
      const data = await response.json();
      throw new Error(data.error || 'Unknown error');
    }

    return response.json();
  }

  formatResponse(data) {
    return {
      body: data.body,
      status: data.status,
      headers: Object.fromEntries(data.headers.map(h => [h.key, h.value])),
      size: data.size
    };
  }

  getClientUrl() {
    return this.contextPath + this.CLIENT_URL;
  }
}

export default APIClient;
