import { API_BASE_URL } from './api-config';

/**
 * ExternalAPI - Wrapper für externe API-Aufrufe mit HTTPS-Unterstützung
 * Enthält Logik für Offline-Fallback und Behandlung von selbstsignierten Zertifikaten
 */
export class ExternalAPI {
  private baseURL: string | { primary: string; fallbacks: string[] };
  private activeURL: string | null = null;

  constructor() {
    this.baseURL = API_BASE_URL;
    // Wenn das API_BASE_URL ein Objekt ist, setzen wir die primäre URL als aktiv
    if (typeof this.baseURL === 'object' && this.baseURL.primary) {
      this.activeURL = this.baseURL.primary;
    } else if (typeof this.baseURL === 'string') {
      this.activeURL = this.baseURL;
    }
  }

  /**
   * Führt einen API-Request durch mit Unterstützung für selbstsignierte Zertifikate
   * und Fallback-URLs wenn die primäre Verbindung fehlschlägt
   */
  async fetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
    // Wenn wir ein Objekt mit mehreren URLs haben
    if (typeof this.baseURL === 'object' && this.baseURL.primary && this.baseURL.fallbacks) {
      // Versuche zuerst die aktive URL (primär oder eine der Fallbacks)
      if (this.activeURL) {
        try {
          const response = await this.fetchFromUrl<T>(this.activeURL + endpoint, options);
          // Wenn erfolgreich, behalte diese URL bei
          return response;
        } catch (error) {
          console.warn(`Verbindung zu ${this.activeURL} fehlgeschlagen, versuche Fallbacks...`);
          
          // Wenn primäre URL fehlschlägt, versuche alle Fallbacks
          const allUrls = [this.baseURL.primary, ...this.baseURL.fallbacks];
          
          // Versuche alle URLs nacheinander (außer der bereits fehlgeschlagenen aktiven URL)
          for (const url of allUrls) {
            if (url === this.activeURL) continue; // Überspringe die bereits versuchte URL
            
            try {
              const response = await this.fetchFromUrl<T>(url + endpoint, options);
              // Wenn erfolgreich, setze diese URL als neue aktive URL
              this.activeURL = url;
              console.log(`Verbindung zu ${url} erfolgreich hergestellt.`);
              return response;
            } catch (fallbackError) {
              // Fehlgeschlagenen Fallback ignorieren und nächsten versuchen
              console.warn(`Fallback ${url} fehlgeschlagen...`);
            }
          }
          
          // Wenn alle Versuche fehlschlagen, wirf den ursprünglichen Fehler
          throw new Error(`Keine Verbindung zum Backend möglich. Alle Verbindungsversuche fehlgeschlagen.`);
        }
      }
    }
    
    // Fallback für einfache String-URL
    return this.fetchFromUrl<T>((this.activeURL || this.baseURL as string) + endpoint, options);
  }
  
  /**
   * Führt einen Fetch-Aufruf an einer bestimmten URL durch
   */
  private async fetchFromUrl<T>(url: string, options: RequestInit = {}): Promise<T> {
    try {
      const response = await fetch(url, {
        ...options,
        headers: {
          'Content-Type': 'application/json',
          ...options.headers,
        },
      });

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

      return await response.json();
    } catch (error) {
      console.error(`API Fehler (${url}):`, error);
      
      // Prüfen auf Zertifikatsfehler
      if (error instanceof Error && error.message.includes('certificate')) {
        console.warn(`Zertifikatsfehler bei ${url}: Bitte akzeptieren Sie das selbstsignierte Zertifikat manuell.`);
      }
      
      throw error;
    }
  }

  // API-Methoden für verschiedene Endpoints
  async getPrinters() {
    return this.fetch<any>('/api/printers');
  }

  async getJobs() {
    return this.fetch<any>('/api/jobs');
  }
}