import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { HealthEndpoint } from './endpoints/health/handler';
import { APIKeyEndpoint } from './endpoints/apikey/handler';
import { LogsEndpoint } from './endpoints/logs/handler';
import { MetricsEndpoint } from './endpoints/metrics/handler';
import { ItemsEndpoint } from './endpoints/items/handler';
import { IntelligenceEndpoint } from './endpoints/intelligence/handler';
import { AnalyzeEndpoint } from './endpoints/analyze/handler';
import { AppEndpoint } from './endpoints/app/handler';

const BASE_URL = 'https://watchtower-go-supabase-822142465400.europe-west1.run.app';

export class WatchtowerSDK {
  private client: AxiosInstance;
  public readonly health: HealthEndpoint;
  public readonly apikey: APIKeyEndpoint;
  public readonly logs: LogsEndpoint;
  public readonly metrics: MetricsEndpoint;
  public readonly items: ItemsEndpoint;
  public readonly intelligence: IntelligenceEndpoint;
  public readonly analyze: AnalyzeEndpoint;
  public readonly app: AppEndpoint;

  constructor(config?: AxiosRequestConfig) {
    this.client = axios.create({
      baseURL: BASE_URL,
      ...config,
    });

    // Initialize endpoints
    this.health = new HealthEndpoint(this.client);
    this.apikey = new APIKeyEndpoint(this.client);
    this.logs = new LogsEndpoint(this.client);
    this.metrics = new MetricsEndpoint(this.client);
    this.items = new ItemsEndpoint(this.client);
    this.intelligence = new IntelligenceEndpoint(this.client);
    this.analyze = new AnalyzeEndpoint(this.client);
    this.app = new AppEndpoint(this.client);
  }

  /**
   * Make a GET request
   * @param url - The endpoint URL
   * @param config - Optional Axios request configuration
   * @returns Promise with the response data
   */
  async get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.client.get(url, config);
    return response.data;
  }

  /**
   * Make a POST request
   * @param url - The endpoint URL
   * @param data - The data to send
   * @param config - Optional Axios request configuration
   * @returns Promise with the response data
   */
  async post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.client.post(url, data, config);
    return response.data;
  }

  /**
   * Make a PUT request
   * @param url - The endpoint URL
   * @param data - The data to send
   * @param config - Optional Axios request configuration
   * @returns Promise with the response data
   */
  async put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.client.put(url, data, config);
    return response.data;
  }

  /**
   * Make a DELETE request
   * @param url - The endpoint URL
   * @param config - Optional Axios request configuration
   * @returns Promise with the response data
   */
  async delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    const response: AxiosResponse<T> = await this.client.delete(url, config);
    return response.data;
  }

  /**
   * Get the underlying Axios instance
   * @returns The Axios instance
   */
  getClient(): AxiosInstance {
    return this.client;
  }
} 