/**
 * API Client for E2E tests
 * Provides typed methods for API interactions
 */

import { APIRequestContext, request } from '@playwright/test';

export class ApiClient {
  private context: APIRequestContext | null = null;
  private baseUrl: string;
  private authToken: string | null = null;

  constructor(baseUrl: string = 'http://localhost:8000') {
    this.baseUrl = baseUrl;
  }

  async init() {
    this.context = await request.newContext({
      baseURL: this.baseUrl,
    });
  }

  async dispose() {
    await this.context?.dispose();
  }

  setAuthToken(token: string) {
    this.authToken = token;
  }

  private getHeaders(): Record<string, string> {
    const headers: Record<string, string> = {
      'Content-Type': 'application/json',
    };
    
    if (this.authToken) {
      headers['Authorization'] = `Bearer ${this.authToken}`;
    }
    
    return headers;
  }

  // Auth endpoints
  async login(email: string, password: string) {
    if (!this.context) await this.init();
    
    const response = await this.context!.post('/api/v1/auth/login', {
      data: { username: email, password },
    });
    
    if (response.ok()) {
      const data = await response.json();
      this.authToken = data.access_token;
    }
    
    return response;
  }

  async register(email: string, password: string, fullName: string) {
    if (!this.context) await this.init();
    
    return this.context!.post('/api/v1/auth/register', {
      data: { email, password, full_name: fullName },
    });
  }

  async refreshToken(refreshToken: string) {
    if (!this.context) await this.init();
    
    return this.context!.post('/api/v1/auth/refresh', {
      data: { refresh_token: refreshToken },
    });
  }

  // Scenario endpoints
  async getScenarios(params?: { page?: number; page_size?: number; status?: string }) {
    if (!this.context) await this.init();
    
    const searchParams = new URLSearchParams();
    if (params?.page) searchParams.append('page', params.page.toString());
    if (params?.page_size) searchParams.append('page_size', params.page_size.toString());
    if (params?.status) searchParams.append('status', params.status);
    
    return this.context!.get(`/api/v1/scenarios?${searchParams}`, {
      headers: this.getHeaders(),
    });
  }

  async getScenario(id: string) {
    if (!this.context) await this.init();
    
    return this.context!.get(`/api/v1/scenarios/${id}`, {
      headers: this.getHeaders(),
    });
  }

  async createScenario(data: {
    name: string;
    description?: string;
    region: string;
    tags?: string[];
  }) {
    if (!this.context) await this.init();
    
    return this.context!.post('/api/v1/scenarios', {
      data,
      headers: this.getHeaders(),
    });
  }

  async updateScenario(id: string, data: Partial<{
    name: string;
    description: string;
    region: string;
    tags: string[];
  }>) {
    if (!this.context) await this.init();
    
    return this.context!.put(`/api/v1/scenarios/${id}`, {
      data,
      headers: this.getHeaders(),
    });
  }

  async deleteScenario(id: string) {
    if (!this.context) await this.init();
    
    return this.context!.delete(`/api/v1/scenarios/${id}`, {
      headers: this.getHeaders(),
    });
  }

  // Metrics endpoints
  async getDashboardMetrics() {
    if (!this.context) await this.init();
    
    return this.context!.get('/api/v1/metrics/dashboard', {
      headers: this.getHeaders(),
    });
  }

  async getScenarioMetrics(scenarioId: string) {
    if (!this.context) await this.init();
    
    return this.context!.get(`/api/v1/scenarios/${scenarioId}/metrics`, {
      headers: this.getHeaders(),
    });
  }

  // Report endpoints
  async getReports(scenarioId: string) {
    if (!this.context) await this.init();
    
    return this.context!.get(`/api/v1/scenarios/${scenarioId}/reports`, {
      headers: this.getHeaders(),
    });
  }

  async generateReport(scenarioId: string, format: 'pdf' | 'csv', includeLogs: boolean = true) {
    if (!this.context) await this.init();
    
    return this.context!.post(`/api/v1/scenarios/${scenarioId}/reports`, {
      data: { format, include_logs: includeLogs },
      headers: this.getHeaders(),
    });
  }

  // Ingest endpoints
  async ingestLog(scenarioId: string, log: {
    message: string;
    source?: string;
    level?: string;
    metadata?: Record<string, unknown>;
  }) {
    if (!this.context) await this.init();
    
    return this.context!.post('/ingest', {
      data: log,
      headers: {
        ...this.getHeaders(),
        'X-Scenario-ID': scenarioId,
      },
    });
  }

  // Health check
  async healthCheck() {
    if (!this.context) await this.init();
    
    return this.context!.get('/health');
  }
}
