// API client for backend communication

import type { 
  EvaluationResponse, 
  CategoryInfo, 
  ValidationMetrics,
  ModelInfo,
  HealthResponse 
} from '@/types';

const API_BASE = '/api';

// Generic fetch wrapper with error handling
async function fetchAPI<T>(
  endpoint: string,
  options?: RequestInit
): Promise<T> {
  const url = `${API_BASE}${endpoint}`;
  
  try {
    const response = await fetch(url, {
      ...options,
      headers: {
        ...options?.headers,
      },
    });
    
    if (!response.ok) {
      const error = await response.json().catch(() => ({ detail: 'Unknown error' }));
      throw new Error(error.detail || `HTTP ${response.status}`);
    }
    
    return response.json();
  } catch (error) {
    console.error(`API Error [${endpoint}]:`, error);
    throw error;
  }
}

// Health check
export async function checkHealth(): Promise<HealthResponse> {
  return fetchAPI<HealthResponse>('/health');
}

// Get categories
export async function getCategories(): Promise<{ categories: CategoryInfo[] }> {
  return fetchAPI<{ categories: CategoryInfo[] }>('/categories');
}

// Get subcategories for a category
export async function getSubcategories(category: string): Promise<{ subcategories: string[] }> {
  return fetchAPI<{ subcategories: string[] }>(`/subcategories?category=${encodeURIComponent(category)}`);
}

// Evaluate product
export async function evaluateProduct(
  title: string,
  description: string,
  category: string,
  subcategory: string | null,
  images: File[],
  imageUrl?: string, // Optional URL for suggestion products
  cnnEmbedding?: number[], // Pre-computed CNN embedding (for suggestions)
  clipEmbedding?: number[], // Pre-computed CLIP embedding (for suggestions)
  cnnPcaFeatures?: Record<string, number>, // Pre-computed CNN PCA features (for suggestions with existing dataset)
  clipPcaFeatures?: Record<string, number>, // Pre-computed CLIP PCA features (for suggestions with existing dataset)
  price?: number // Product price in USD
): Promise<EvaluationResponse> {
  const formData = new FormData();
  formData.append('title', title);
  formData.append('description', description);
  formData.append('category', category);
  if (subcategory) {
    formData.append('subcategory', subcategory);
  }
  
  // Append images if provided
  if (images && images.length > 0) {
    images.forEach((image) => {
      formData.append('images', image);
    });
  }
  
  // Append image URL if no images but URL provided (for suggestions)
  if (imageUrl && (!images || images.length === 0)) {
    formData.append('image_url', imageUrl);
  }
  
  // Append price if provided
  if (price !== undefined && price > 0) {
    formData.append('price', price.toString());
  }

  // Prefer pre-computed PCA features if available (dataset already has PCA features)
  if (cnnPcaFeatures && clipPcaFeatures) {
    formData.append('cnn_pca_json', JSON.stringify(cnnPcaFeatures));
    formData.append('clip_pca_json', JSON.stringify(clipPcaFeatures));
  } else if (cnnEmbedding && clipEmbedding) {
    // Fall back to raw embeddings (will apply PCA)
    formData.append('cnn_embedding_json', JSON.stringify(cnnEmbedding));
    formData.append('clip_embedding_json', JSON.stringify(clipEmbedding));
  }
  
  return fetchAPI<EvaluationResponse>('/evaluate', {
    method: 'POST',
    body: formData,
  });
}

// Get models
export async function getModels(): Promise<{ 
  embedding_model_loaded: boolean;
  category_models: ModelInfo[];
}> {
  return fetchAPI('/models');
}

// Get validation summary
export async function getValidationSummary(): Promise<{
  overall_auc: number;
  overall_f1: number;
  overall_r2?: number;
  overall_mae?: number;
  by_category: ValidationMetrics[];
  calibration_summary: Record<string, number | string>;
}> {
  return fetchAPI('/validation/summary');
}

// Get API examples
export async function getAPIExamples(): Promise<Record<string, unknown>> {
  return fetchAPI('/api-examples');
}

// Get sample product suggestions
export async function getSuggestions(category?: string): Promise<{
  suggestions: Record<string, Array<{
    title: string;
    description: string;
    category: string;
    image_url: string;
    asin: string;
    actual_bsr: number | null;
    has_bsr: boolean;
  }>>;
}> {
  const endpoint = category 
    ? `/suggestions?category=${encodeURIComponent(category)}`
    : '/suggestions';
  return fetchAPI(endpoint);
}

// Extract image embeddings (for debugging)
export async function extractImageEmbeddings(image: File): Promise<{
  valid: boolean;
  quality_metrics: Record<string, number>;
  composition_metrics: Record<string, number>;
  embedding_stats: { cnn_dim: number; clip_dim: number };
}> {
  const formData = new FormData();
  formData.append('image', image);
  
  return fetchAPI('/embeddings/image', {
    method: 'POST',
    body: formData,
  });
}
