/**
 * Training service API implementation
 * Handles all training-related backend communications
 */

import { apiClient } from '../client/apiClient';
import type {
  TrainingJobRequest,
  TrainingJobResponse,
  TrainingJobStatus,
  SingleProductTrainingRequest,
  ActiveModelResponse,
  ModelMetricsResponse,
  TrainedModelResponse,
  TenantStatistics,
  ModelPerformanceResponse,
  ModelsQueryParams,
  PaginatedResponse,
} from '../types/training';

class TrainingService {
  private readonly baseUrl = '/tenants';

  // Training Jobs
  async createTrainingJob(
    tenantId: string, 
    request: TrainingJobRequest
  ): Promise<TrainingJobResponse> {
    return apiClient.post<TrainingJobResponse>(
      `${this.baseUrl}/${tenantId}/training/jobs`,
      request
    );
  }

  async trainSingleProduct(
    tenantId: string,
    inventoryProductId: string,
    request: SingleProductTrainingRequest
  ): Promise<TrainingJobResponse> {
    return apiClient.post<TrainingJobResponse>(
      `${this.baseUrl}/${tenantId}/training/products/${inventoryProductId}`,
      request
    );
  }

  async getTrainingJobStatus(
    tenantId: string,
    jobId: string
  ): Promise<TrainingJobStatus> {
    return apiClient.get<TrainingJobStatus>(
      `${this.baseUrl}/${tenantId}/training/jobs/${jobId}/status`
    );
  }

  // Models Management
  async getActiveModel(
    tenantId: string,
    inventoryProductId: string
  ): Promise<ActiveModelResponse> {
    return apiClient.get<ActiveModelResponse>(
      `${this.baseUrl}/${tenantId}/models/${inventoryProductId}/active`
    );
  }

  async getModelMetrics(
    tenantId: string,
    modelId: string
  ): Promise<ModelMetricsResponse> {
    return apiClient.get<ModelMetricsResponse>(
      `${this.baseUrl}/${tenantId}/models/${modelId}/metrics`
    );
  }

  async getModels(
    tenantId: string,
    queryParams?: ModelsQueryParams
  ): Promise<PaginatedResponse<TrainedModelResponse>> {
    const params = new URLSearchParams();
    if (queryParams?.status) params.append('status', queryParams.status);
    if (queryParams?.model_type) params.append('model_type', queryParams.model_type);
    if (queryParams?.limit) params.append('limit', queryParams.limit.toString());
    if (queryParams?.offset) params.append('offset', queryParams.offset.toString());

    const queryString = params.toString() ? `?${params.toString()}` : '';
    return apiClient.get<PaginatedResponse<TrainedModelResponse>>(
      `${this.baseUrl}/${tenantId}/models/${queryString}`
    );
  }

  async getModelPerformance(
    tenantId: string,
    modelId: string
  ): Promise<ModelPerformanceResponse> {
    return apiClient.get<ModelPerformanceResponse>(
      `${this.baseUrl}/${tenantId}/models/${modelId}/performance`
    );
  }

  // Statistics and Analytics
  async getTenantStatistics(tenantId: string): Promise<TenantStatistics> {
    return apiClient.get<TenantStatistics>(
      `${this.baseUrl}/${tenantId}/statistics`
    );
  }

  // Admin endpoints (requires admin role)
  async deleteAllTenantModels(tenantId: string): Promise<{ message: string }> {
    return apiClient.delete<{ message: string }>(`/models/tenant/${tenantId}`);
  }

  // WebSocket connection helper (for real-time training updates)
  getTrainingWebSocketUrl(tenantId: string, jobId: string): string {
    const baseWsUrl = apiClient.getAxiosInstance().defaults.baseURL?.replace(/^http/, 'ws');
    return `${baseWsUrl}/ws/tenants/${tenantId}/training/jobs/${jobId}/live`;
  }

  // Helper method to construct WebSocket connection
  createWebSocketConnection(
    tenantId: string,
    jobId: string,
    token?: string
  ): WebSocket {
    const wsUrl = this.getTrainingWebSocketUrl(tenantId, jobId);
    const urlWithToken = token ? `${wsUrl}?token=${token}` : wsUrl;
    
    return new WebSocket(urlWithToken);
  }
}

// Create and export singleton instance
export const trainingService = new TrainingService();
export default trainingService;