import { BaseEndpoint } from '../base';
import { 
  GetLatestRequest, 
  AnalyzeLogsRequest, 
  AnalyzeCurrentRequest,
  AnalyzeCurrentResponse,
  AnalysisResult 
} from './types';
import { InvalidRequestError, AuthenticationError, ServerError } from '../../errors';

export class AnalyzeEndpoint extends BaseEndpoint {
  constructor(client: any) {
    super(client, '/api/analyze');
  }

  private validateRequiredKeys(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 the latest analysis for an item
   * @param data - The request parameters
   * @returns Promise with the analysis result
   * @throws {InvalidRequestError} If required fields are missing or invalid
   * @throws {AuthenticationError} If API keys are invalid
   * @throws {ServerError} If server encounters an error
   */
  async getLatest(data: GetLatestRequest): Promise<AnalysisResult> {
    this.validateRequiredKeys(data);

    if (!data.item_id) {
      throw new InvalidRequestError('item_id is required');
    }

    try {
      return await this.get<AnalysisResult>('/latest', { 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;
    }
  }

  /**
   * Analyze logs for an item within a specified time range
   * @param data - The request parameters
   * @returns Promise with the analysis result
   * @throws {InvalidRequestError} If required fields are missing or invalid
   * @throws {AuthenticationError} If API keys are invalid
   * @throws {ServerError} If server encounters an error
   */
  async analyzeLogs(data: AnalyzeLogsRequest): Promise<AnalysisResult> {
    this.validateRequiredKeys(data);

    if (!data.item_id) {
      throw new InvalidRequestError('item_id is required');
    }

    // Validate timestamp format if provided
    if (data.after && !this.isValidISODate(data.after)) {
      throw new InvalidRequestError('after must be a valid ISO 8601 timestamp');
    }
    if (data.before && !this.isValidISODate(data.before)) {
      throw new InvalidRequestError('before must be a valid ISO 8601 timestamp');
    }

    try {
      return await this.get<AnalysisResult>('', { 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 the current analysis for an item
   * @param data - The request parameters
   * @returns Promise with the current analysis response
   * @throws {InvalidRequestError} If required fields are missing or invalid
   * @throws {AuthenticationError} If API keys are invalid
   * @throws {ServerError} If server encounters an error
   */
  async analyzeCurrent(data: AnalyzeCurrentRequest): Promise<AnalyzeCurrentResponse> {
    this.validateRequiredKeys(data);

    if (!data.item_id) {
      throw new InvalidRequestError('item_id is required');
    }

    try {
      return await this.get<AnalyzeCurrentResponse>('/current', { 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;
    }
  }

  /**
   * Validate if a string is a valid ISO 8601 date
   * @param dateString - The date string to validate
   * @returns boolean indicating if the string is a valid ISO 8601 date
   */
  private isValidISODate(dateString: string): boolean {
    const date = new Date(dateString);
    return date instanceof Date && !isNaN(date.getTime()) && dateString === date.toISOString();
  }
} 