/**
 * Canonicalization: map Brand industry + location fields to the
 * (vertical, locale) cells used by the Market Position pipeline.
 *
 * Verticals are coarse-grained buckets that can hold a stable corpus
 * and calibration model. Locales are "metro:<slug>" for locally-
 * competitive industries or "national" for everything else.
 */

import { getBrandLocations } from "@/lib/brand-helpers";

// ---------------------------------------------------------------------------
// Vertical map
// ---------------------------------------------------------------------------

// Maps every known Industry Classifier output to a canonical vertical.
// Aliases (lowercase, stripped of hyphens/spaces) are checked when the
// direct key does not match -- handles minor classifier drift.
const INDUSTRY_TO_VERTICAL: Record<string, string> = {
  // healthcare
  "healthcare-medical": "healthcare",
  "healthcare-dental": "dental",
  "healthcare-mental-health": "mental-health",
  "healthcare-veterinary": "veterinary",
  "healthcare-other": "healthcare",
  // b2b
  "b2b-saas": "b2b-saas",
  "b2b-services": "b2b-services",
  "b2b-manufacturing": "b2b-manufacturing",
  "b2b-finance": "finance",
  "b2b-legal": "legal",
  "b2b-other": "b2b-services",
  // ecommerce variants
  "ecommerce": "ecommerce",
  "ecommerce-fashion": "ecommerce",
  "ecommerce-beauty": "ecommerce",
  "ecommerce-electronics": "ecommerce",
  "ecommerce-home": "ecommerce",
  "ecommerce-sports": "ecommerce",
  "ecommerce-food": "ecommerce",
  "ecommerce-other": "ecommerce",
  // standalone categories
  "local-services": "local-services",
  "professional-services": "professional-services",
  "finance": "finance",
  "legal": "legal",
  "real-estate": "real-estate",
  "nonprofit": "nonprofit",
  "hospitality": "hospitality",
  "higher-ed": "higher-ed",
  "other": "other",
};

// Verticals where local market share is meaningful -- gets metro locale.
const LOCAL_VERTICALS = new Set([
  "dental",
  "healthcare",
  "mental-health",
  "veterinary",
  "local-services",
  "real-estate",
  "hospitality",
  "legal",
  "professional-services",
]);

export function canonicalizeVertical(industry: string | null | undefined): string {
  if (!industry) return "other";
  const key = industry.toLowerCase().trim();
  if (INDUSTRY_TO_VERTICAL[key]) return INDUSTRY_TO_VERTICAL[key];
  // Fuzzy: strip hyphens/spaces and try prefix matching
  const stripped = key.replace(/[-\s]/g, "");
  for (const [k, v] of Object.entries(INDUSTRY_TO_VERTICAL)) {
    if (k.replace(/[-\s]/g, "") === stripped) return v;
  }
  if (key.startsWith("healthcare")) return "healthcare";
  if (key.startsWith("b2b")) return "b2b-services";
  if (key.startsWith("ecommerce")) return "ecommerce";
  return "other";
}

// ---------------------------------------------------------------------------
// Locale canonicalization
// ---------------------------------------------------------------------------

// Common city-name normalization (lowercase slug).
// Covers major US metros that appear frequently in Brand.location.
const METRO_ALIASES: Record<string, string> = {
  "new york": "new-york",
  "new york city": "new-york",
  "nyc": "new-york",
  "los angeles": "los-angeles",
  "la": "los-angeles",
  "chicago": "chicago",
  "houston": "houston",
  "phoenix": "phoenix",
  "philadelphia": "philadelphia",
  "san antonio": "san-antonio",
  "san diego": "san-diego",
  "dallas": "dallas",
  "san jose": "san-jose",
  "austin": "austin",
  "jacksonville": "jacksonville",
  "fort worth": "fort-worth",
  "columbus": "columbus",
  "charlotte": "charlotte",
  "san francisco": "san-francisco",
  "sf": "san-francisco",
  "indianapolis": "indianapolis",
  "seattle": "seattle",
  "denver": "denver",
  "washington": "washington-dc",
  "washington dc": "washington-dc",
  "nashville": "nashville",
  "oklahoma city": "oklahoma-city",
  "el paso": "el-paso",
  "boston": "boston",
  "portland": "portland",
  "las vegas": "las-vegas",
  "memphis": "memphis",
  "louisville": "louisville",
  "baltimore": "baltimore",
  "milwaukee": "milwaukee",
  "atlanta": "atlanta",
  "miami": "miami",
  "minneapolis": "minneapolis",
  "tampa": "tampa",
  "new orleans": "new-orleans",
  "cleveland": "cleveland",
  "pittsburgh": "pittsburgh",
  "detroit": "detroit",
  "raleigh": "raleigh",
  "richmond": "richmond",
  "sacramento": "sacramento",
  "salt lake city": "salt-lake-city",
  "kansas city": "kansas-city",
  "orlando": "orlando",
};

export function canonicalizeMetro(location: string): string {
  const lower = location.toLowerCase().trim();
  // Try exact match
  if (METRO_ALIASES[lower]) return METRO_ALIASES[lower];
  // Try stripping state suffix: "Austin, TX" -> "austin"
  const cityPart = lower.split(/[,;]/)[0].trim();
  if (METRO_ALIASES[cityPart]) return METRO_ALIASES[cityPart];
  // Slug-ify whatever we got
  return cityPart.replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "unknown";
}

// ---------------------------------------------------------------------------
// Cell derivation
// ---------------------------------------------------------------------------

export interface Cell {
  vertical: string;
  locale: string;
}

export interface BrandCellFields {
  industry?: string | null;
  location?: string | null;
  locations?: string[] | null;
}

/**
 * Return the (vertical, locale) cells a brand belongs to.
 * Every brand gets a national cell. Local-competitive verticals
 * also get one cell per distinct metro derived from Brand.locations.
 */
export function getBrandCells(brand: BrandCellFields): Cell[] {
  const vertical = canonicalizeVertical(brand.industry);
  const cells: Cell[] = [{ vertical, locale: "national" }];

  if (LOCAL_VERTICALS.has(vertical)) {
    const locations = getBrandLocations(brand);
    const seen = new Set<string>();
    for (const loc of locations) {
      const metro = canonicalizeMetro(loc);
      if (metro && metro !== "unknown" && !seen.has(metro)) {
        seen.add(metro);
        cells.push({ vertical, locale: `metro:${metro}` });
      }
    }
  }

  return cells;
}
