import type { Product } from "@/types/product";

/** Ranking of a single product against a query, with the per-stage scores exposed. */
export interface ScoredProduct {
  product: Product;
  /** Final blended relevance score, 0..1. */
  score: number;
  /** Cosine similarity between the query vector and the product vector, 0..1. */
  similarity: number;
  /** Normalised keyword (BM25-style) relevance, 0..1. */
  keywordScore: number;
  /** Price intent component, 0..1. Only non-zero when the query carries a price signal. */
  priceScore: number;
  /** Query terms that matched this product's text, used for "why did this match?" hints. */
  matchedTerms: string[];
}

export type ProductSort =
  | "relevance"
  | "price-asc"
  | "price-desc"
  | "rating-desc"
  | "name-asc";

export interface ProductFilters {
  category?: string;
  brand?: string;
  minPrice?: number;
  maxPrice?: number;
  minRating?: number;
  inStockOnly?: boolean;
}

export interface SearchRequest {
  query: string;
  filters: ProductFilters;
  sort: ProductSort;
  limit: number;
}

export interface SearchFacets {
  categories: string[];
  brands: string[];
  priceRange: { min: number; max: number };
}

export interface SearchMeta {
  query: string;
  total: number;
  returned: number;
  /** How long the vector comparison took, in milliseconds. */
  took: number;
  /** Which embedding provider produced the vectors. */
  provider: string;
  providerFallback: boolean;
  sort: ProductSort;
  weights: RankingWeights;
  priceIntent: PriceIntent;
}

export interface SearchResponse {
  results: ScoredProduct[];
  meta: SearchMeta;
  suggestions: string[];
}

export interface SearchError {
  error: {
    code: string;
    message: string;
    details?: Record<string, string[]>;
  };
}

export type PriceIntent = "none" | "budget" | "premium";

/** Blending weights for the hybrid ranker. Configurable, never hard-coded at call sites. */
export interface RankingWeights {
  semantic: number;
  keyword: number;
  price: number;
}

export interface ParsedSearchInput {
  query: string;
  filters: ProductFilters;
  sort: ProductSort;
  limit: number;
}

export interface QueryAnalysis {
  /** Query after stop-word removal and intent expansion. */
  expandedQuery: string;
  terms: string[];
  priceIntent: PriceIntent;
  /** Explicit price ceiling found in the query, e.g. "under 100" -> 100. */
  priceCeiling: number | null;
}