import type { RankingWeights } from "@/types/search";

/**
 * Ranking configuration.
 *
 * The blend described in the spec is the default:
 *
 *   Final Score = Semantic Similarity x 0.70 + Keyword Score x 0.30
 *
 * The price term is a third, optional component that only activates when the
 * query carries a price signal ("cheap", "budget", "premium"), so ordinary
 * queries are not silently biased towards cheap products.
 */

export const DEFAULT_WEIGHTS: RankingWeights = {
  semantic: 0.7,
  keyword: 0.3,
  price: 0,
};

export const PRICE_WEIGHT_BUDGET = 0.15;
export const PRICE_WEIGHT_PREMIUM = 0.1;

function readWeight(name: string, fallback: number, max = 1): number {
  const parsed = Number.parseFloat(process.env[name] ?? "");
  if (!Number.isFinite(parsed) || parsed < 0) return fallback;
  return Math.min(parsed, max);
}

/**
 * Weights for a request, overridable through the environment. The three
 * components are renormalised to sum to 1 so that scores stay comparable when
 * a component is added or removed.
 */
export function getWeights(priceActive: boolean): RankingWeights {
  const weights: RankingWeights = {
    semantic: readWeight("SEARCH_WEIGHT_SEMANTIC", DEFAULT_WEIGHTS.semantic),
    keyword: readWeight("SEARCH_WEIGHT_KEYWORD", DEFAULT_WEIGHTS.keyword),
    price: priceActive
      ? readWeight("SEARCH_WEIGHT_PRICE", PRICE_WEIGHT_BUDGET, PRICE_WEIGHT_BUDGET)
      : 0,
  };
  return normalizeWeights(weights);
}

export function normalizeWeights(weights: RankingWeights): RankingWeights {
  const total = weights.semantic + weights.keyword + weights.price;
  if (total <= 0) return { ...DEFAULT_WEIGHTS, price: 0 };
  return {
    semantic: weights.semantic / total,
    keyword: weights.keyword / total,
    price: weights.price / total,
  };
}

/** Below this blended score a product is not worth showing as a match. */
export const RELEVANCE_FLOOR = 0.12;

export const SEARCH_LIMITS = {
  queryMaxLength: 200,
  minLimit: 1,
  maxLimit: 50,
  defaultLimit: 24,
} as const;

export const SORT_OPTIONS = [
  "relevance",
  "price-asc",
  "price-desc",
  "rating-desc",
  "name-asc",
] as const;
