import { BaseEndpoint } from '../base';
import { 
  GetMetricsRequest, 
  GetMetricsResponse, 
  GetAppMetadataRequest, 
  GetAppMetadataResponse,
  GetTenantMetadataRequest,
  GetTenantMetadataResponse
} from './types';
import { InvalidRequestError, AuthenticationError, ServerError } from '../../errors';

export class MetricsEndpoint extends BaseEndpoint {
  constructor(client: any) {
    super(client, '/api/metrics');
  }

  private validateRequiredKeys(data: { organization_apikey?: string; app_apikey?: string; tenant_apikey?: string }) {
    if (!data.organization_apikey) {
      throw new InvalidRequestError('organization_apikey is required');
    }
    if (!data.app_apikey) {
      throw new InvalidRequestError('app_apikey is required');
    }
    if (data.tenant_apikey === undefined) {
      throw new InvalidRequestError('tenant_apikey is required');
    }
  }

  private validateAppKeys(data: { organization_apikey?: string; app_apikey?: string }) {
    if (!data.organization_apikey) {
      throw new InvalidRequestError('organization_apikey is required');
    }
    if (!data.app_apikey) {
      throw new InvalidRequestError('app_apikey is required');
    }
  }

  /**
   * Get metrics for a specific tenant
   * @param data - The get metrics request parameters
   * @returns Promise with the metrics response
   * @throws {InvalidRequestError} If required fields are missing
   * @throws {AuthenticationError} If API keys are invalid
   * @throws {ServerError} If server encounters an error
   */
  async getMetrics(data: GetMetricsRequest): Promise<GetMetricsResponse> {
    this.validateRequiredKeys(data);

    try {
      return await this.get<GetMetricsResponse>('', { params: data });
    } catch (error: any) {
      if (error.response?.status === 400) {
        throw new InvalidRequestError(error.response.data?.message || 'Invalid request');
      }
      if (error.response?.status === 401) {
        throw new AuthenticationError('Invalid API keys');
      }
      if (error.response?.status === 500) {
        throw new ServerError('Internal server error');
      }
      throw error;
    }
  }

  /**
   * Get metadata for a specific app
   * @param data - The get app metadata request parameters
   * @returns Promise with the app metadata response
   * @throws {InvalidRequestError} If required fields are missing
   * @throws {AuthenticationError} If API keys are invalid
   * @throws {ServerError} If server encounters an error
   */
  async getAppMetadata(data: GetAppMetadataRequest): Promise<GetAppMetadataResponse> {
    this.validateAppKeys(data);

    try {
      return await this.get<GetAppMetadataResponse>('/app', { params: data });
    } catch (error: any) {
      if (error.response?.status === 400) {
        throw new InvalidRequestError(error.response.data?.message || 'Invalid request');
      }
      if (error.response?.status === 401) {
        throw new AuthenticationError('Invalid API keys');
      }
      if (error.response?.status === 500) {
        throw new ServerError('Internal server error');
      }
      throw error;
    }
  }

  /**
   * Get metadata for a specific tenant
   * @param data - The get tenant metadata request parameters
   * @returns Promise with the tenant metadata response
   * @throws {InvalidRequestError} If required fields are missing
   * @throws {AuthenticationError} If API keys are invalid
   * @throws {ServerError} If server encounters an error
   */
  async getTenantMetadata(data: GetTenantMetadataRequest): Promise<GetTenantMetadataResponse> {
    this.validateRequiredKeys(data);

    try {
      return await this.get<GetTenantMetadataResponse>('/tenant', { params: data });
    } catch (error: any) {
      if (error.response?.status === 400) {
        throw new InvalidRequestError(error.response.data?.message || 'Invalid request');
      }
      if (error.response?.status === 401) {
        throw new AuthenticationError('Invalid API keys');
      }
      if (error.response?.status === 500) {
        throw new ServerError('Internal server error');
      }
      throw error;
    }
  }
} 