/**
 * Block 2 verification: canonicalization + fragmentToQuery.
 * Run without a database -- pure logic checks.
 *
 *   node scripts/verify-block2.mjs
 */

// ---- inline the canonicalization logic (mirrors cell.ts) ----

const INDUSTRY_TO_VERTICAL = {
  "healthcare-medical": "healthcare",
  "healthcare-dental": "dental",
  "healthcare-mental-health": "mental-health",
  "healthcare-veterinary": "veterinary",
  "healthcare-other": "healthcare",
  "b2b-saas": "b2b-saas",
  "b2b-services": "b2b-services",
  "b2b-manufacturing": "b2b-manufacturing",
  "b2b-finance": "finance",
  "b2b-legal": "legal",
  "b2b-other": "b2b-services",
  "ecommerce": "ecommerce",
  "ecommerce-fashion": "ecommerce",
  "ecommerce-beauty": "ecommerce",
  "ecommerce-electronics": "ecommerce",
  "ecommerce-home": "ecommerce",
  "ecommerce-sports": "ecommerce",
  "ecommerce-food": "ecommerce",
  "ecommerce-other": "ecommerce",
  "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",
};

const LOCAL_VERTICALS = new Set([
  "dental", "healthcare", "mental-health", "veterinary",
  "local-services", "real-estate", "hospitality", "legal", "professional-services",
]);

const METRO_ALIASES = {
  "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", "charlotte": "charlotte",
  "san francisco": "san-francisco", "sf": "san-francisco",
  "denver": "denver", "boston": "boston", "seattle": "seattle",
  "atlanta": "atlanta", "miami": "miami", "raleigh": "raleigh",
  "nashville": "nashville", "minneapolis": "minneapolis",
};

function canonicalizeVertical(industry) {
  if (!industry) return "other";
  const key = industry.toLowerCase().trim();
  if (INDUSTRY_TO_VERTICAL[key]) return INDUSTRY_TO_VERTICAL[key];
  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";
}

function canonicalizeMetro(location) {
  const lower = location.toLowerCase().trim();
  if (METRO_ALIASES[lower]) return METRO_ALIASES[lower];
  const cityPart = lower.split(/[,;]/)[0].trim();
  if (METRO_ALIASES[cityPart]) return METRO_ALIASES[cityPart];
  return cityPart.replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "unknown";
}

function getBrandLocations(brand) {
  if (brand.locations && brand.locations.length > 0) return brand.locations;
  if (brand.location && brand.location.trim()) return [brand.location.trim()];
  return [];
}

function getBrandCells(brand) {
  const vertical = canonicalizeVertical(brand.industry);
  const cells = [{ vertical, locale: "national" }];
  if (LOCAL_VERTICALS.has(vertical)) {
    const seen = new Set();
    for (const loc of getBrandLocations(brand)) {
      const metro = canonicalizeMetro(loc);
      if (metro && metro !== "unknown" && !seen.has(metro)) {
        seen.add(metro);
        cells.push({ vertical, locale: `metro:${metro}` });
      }
    }
  }
  return cells;
}

// ---- inline fragmentToQuery logic (mirrors seed-corpus.ts) ----

const STOP_WORDS = new Set([
  "the","a","an","and","or","but","in","on","at","to","for","of","with",
  "by","from","is","are","was","were","be","been","has","have","had","do",
  "does","did","will","would","could","should","may","might","can","our",
  "your","their","its","this","that","these","those","we","you","they","it",
  "he","she","i","me","my","us","not","no","so","if","as","up","out","about",
  "into","than","then","when","where","which","who","how","what","why","all",
  "also","just","more","most","other","such","get","use","using","used","new",
  "need","needs","make",
  // common content verbs that appear in AI answer fragments
  "provides","provide","offers","offer","delivers","deliver","includes","include",
  "helps","help","gives","give","allows","allow","enables","enable","features",
  "feature","serves","serve","creates","create","makes","builds","build",
  "brings","bring",
  // qualifiers that add noise
  "same","days","area","near","patients","customers","clients","team","staff",
  "experts","people","many","every","each","both","full","well","come","wide",
  "high","even","here","there","very","always","never","often",
]);

function inferFromLandingPage(url) {
  try {
    const pathname = url.startsWith("http") ? new URL(url).pathname : url;
    const segments = pathname.split("/").filter(Boolean);
    const meaningful = segments.filter(s => s.length > 2 && !/^[a-z]{2}$/.test(s));
    const slug = meaningful[meaningful.length - 1] ?? "";
    if (!slug) return "site visit";
    return slug.replace(/[-_]/g, " ").replace(/\s+/g, " ").trim();
  } catch { return "site visit"; }
}

function fragmentToQuery(fragment, landingPage, brandName) {
  const isInferred = fragment.startsWith("[inferred]");
  if (isInferred) {
    const raw = inferFromLandingPage(landingPage);
    const base = raw === "site visit" || raw.includes(".") ? "" : raw;
    return base ? `best ${base} near me` : `${brandName} services`;
  }
  const brandPattern = new RegExp(brandName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
  const cleaned = fragment.replace(brandPattern, "").replace(/["""'']/g, "").replace(/\s+/g, " ").trim();
  const tokens = cleaned.split(/\W+/)
    .filter(w => w.length > 3 && !STOP_WORDS.has(w.toLowerCase()) && !/^\d+$/.test(w));
  const keywords = tokens.slice(0, 5).join(" ").toLowerCase();
  if (!keywords) return `${brandName} services`;
  return keywords;
}

const COMMERCIAL_CONVERSION_TYPES = new Set([
  "appointment_booked","form_submitted","phone_call","email_contact","sms_contact","purchase",
  "booking_confirmed","form_submit","form_submission","phone_number_click","click_to_call",
  "calendly","email_click","sms_click",
]);

function deriveConversionWeight(converted, dealValue, conversionType) {
  if (!converted) return 0;
  let base = 0.3;
  if (conversionType && COMMERCIAL_CONVERSION_TYPES.has(conversionType.toLowerCase())) base += 0.3;
  if (dealValue !== null) {
    if (dealValue >= 10000) base += 0.4;
    else if (dealValue >= 1000) base += 0.3;
    else if (dealValue >= 100) base += 0.2;
    else base += 0.1;
  }
  return Math.min(base, 1);
}

// ============================================================
// SECTION 1: Multi-vertical cell bucketing
// ============================================================

console.log("\n=== SECTION 1: Multi-vertical cell bucketing ===\n");

const testBrands = [
  { name: "Raleigh Cardiovascular Specialists", industry: "healthcare-medical", location: "Raleigh, NC", locations: ["Raleigh, NC"] },
  { name: "Fairway Lawns",                      industry: "local-services",      location: "Charlotte, NC", locations: ["Charlotte, NC", "Raleigh, NC"] },
  { name: "AiGrowth360",                         industry: "b2b-saas",            location: "United States", locations: [] },
  { name: "TPAction",                            industry: "b2b-services",        location: null,            locations: [] },
  { name: "Happy Smiles Dental",                 industry: "healthcare-dental",   location: "Austin, TX",    locations: ["Austin, TX"] },
];

for (const brand of testBrands) {
  const cells = getBrandCells(brand);
  console.log(`[${brand.name}]`);
  console.log(`  industry="${brand.industry}" -> vertical="${canonicalizeVertical(brand.industry)}"`);
  console.log(`  cells: ${JSON.stringify(cells)}`);
}

// ============================================================
// SECTION 2: Canonicalization coverage (all known classifier outputs)
// ============================================================

console.log("\n=== SECTION 2: Industry -> vertical canonicalization map ===\n");

const allIndustries = [
  "healthcare-medical","healthcare-dental","healthcare-mental-health","healthcare-veterinary","healthcare-other",
  "b2b-saas","b2b-services","b2b-manufacturing","b2b-finance","b2b-legal","b2b-other",
  "ecommerce","ecommerce-fashion","ecommerce-beauty","ecommerce-electronics","ecommerce-home",
  "ecommerce-sports","ecommerce-food","ecommerce-other",
  "local-services","professional-services","finance","legal","real-estate",
  "nonprofit","hospitality","higher-ed","other",
  // Fuzzy / drift cases
  null, "", "Healthcare Medical", "B2B SaaS", "ECOMMERCE", "unknown-industry",
];
for (const ind of allIndustries) {
  console.log(`  ${JSON.stringify(ind).padEnd(32)} -> "${canonicalizeVertical(ind)}"`);
}

// ============================================================
// SECTION 3: fragmentToQuery derivation examples
// ============================================================

console.log("\n=== SECTION 3: fragmentToQuery derivation ===\n");

const fragmentTests = [
  {
    desc: "Medical brand fragment",
    fragment: "Raleigh Cardiovascular Specialists provides comprehensive cardiac imaging and interventional cardiology services for patients throughout central North Carolina",
    landingPage: "https://raleighcardio.com/services/cardiac-imaging",
    brandName: "Raleigh Cardiovascular Specialists",
  },
  {
    desc: "Dental brand fragment",
    fragment: "Happy Smiles Dental offers same-day emergency dental appointments and affordable teeth whitening treatments for Austin area patients",
    landingPage: "https://happysmilesdental.com/emergency-dentist",
    brandName: "Happy Smiles Dental",
  },
  {
    desc: "B2B SaaS fragment",
    fragment: "AiGrowth360 delivers AI-powered marketing automation and lead scoring tools purpose-built for B2B sales teams",
    landingPage: "https://aigrowth360.com/features/lead-scoring",
    brandName: "AiGrowth360",
  },
  {
    desc: "Lawn care (inferred fragment)",
    fragment: "[inferred] lawn care services",
    landingPage: "https://fairwaylawns.com/services/lawn-fertilization",
    brandName: "Fairway Lawns",
  },
  {
    desc: "Empty fragment fallback",
    fragment: "[inferred] site visit",
    landingPage: "https://tpaction.com/",
    brandName: "TPAction",
  },
];

for (const t of fragmentTests) {
  const q = fragmentToQuery(t.fragment, t.landingPage, t.brandName);
  console.log(`[${t.desc}]`);
  console.log(`  fragment: "${t.fragment.slice(0, 80)}..."`);
  console.log(`  derived query: "${q}"`);
}

// ============================================================
// SECTION 4: conversionWeight examples
// ============================================================

console.log("\n=== SECTION 4: deriveConversionWeight examples ===\n");

const weightTests = [
  { converted: false,  dealValue: 5000,  conversionType: "appointment_booked",  label: "unconverted (no weight)" },
  { converted: true,   dealValue: null,   conversionType: null,                   label: "converted, no type, no value" },
  { converted: true,   dealValue: null,   conversionType: "appointment_booked",   label: "converted, commercial type, no value" },
  { converted: true,   dealValue: 250,    conversionType: "appointment_booked",   label: "converted, commercial type, dealValue=250" },
  { converted: true,   dealValue: 2500,   conversionType: "form_submitted",       label: "converted, commercial type, dealValue=2500" },
  { converted: true,   dealValue: 15000,  conversionType: "purchase",             label: "converted, purchase, dealValue=15000 (cap)" },
  { converted: true,   dealValue: null,   conversionType: "phone_call",           label: "converted, phone_call (old type)" },
  { converted: true,   dealValue: null,   conversionType: "phone_number_click",   label: "converted, phone_number_click (legacy)" },
  { converted: true,   dealValue: null,   conversionType: "unknown_type",         label: "converted, unrecognized type (no bonus)" },
];

for (const t of weightTests) {
  const w = deriveConversionWeight(t.converted, t.dealValue, t.conversionType);
  console.log(`  [${t.label}]`);
  console.log(`    converted=${t.converted} dealValue=${t.dealValue} convType=${t.conversionType} -> weight=${w.toFixed(2)}`);
}

// ============================================================
// SECTION 5: Simulated corpus for one cell (healthcare/national)
// ============================================================

console.log("\n=== SECTION 5: Simulated FRAGMENT_SEEDED corpus (healthcare, national) ===\n");

const healthcareSampleAttributions = [
  { brandId: "b1", queryContext: "Raleigh Cardiovascular provides cardiac imaging and heart failure management for patients", landingPage: "https://raleighcardio.com/cardiac-imaging", converted: true, dealValue: 3000, conversionType: "appointment_booked" },
  { brandId: "b1", queryContext: "interventional cardiology procedures including stent placement and catheterization", landingPage: "https://raleighcardio.com/procedures", converted: false, dealValue: null, conversionType: null },
  { brandId: "b1", queryContext: null, landingPage: "https://raleighcardio.com/pediatric-cardiology", converted: true, dealValue: 500, conversionType: "form_submitted" },
  { brandId: "b2", queryContext: "same-day urgent care and family medicine appointments available", landingPage: "https://example-medical.com/urgent-care", converted: true, dealValue: null, conversionType: "appointment_booked" },
];

const brandNames = new Map([["b1", "Raleigh Cardiovascular"], ["b2", "Example Medical Group"]]);
const weightMap = new Map();

for (const attr of healthcareSampleAttributions) {
  const fragment = attr.queryContext ?? `[inferred] site visit`;
  const brandName = brandNames.get(attr.brandId) ?? "";
  const query = fragmentToQuery(fragment, attr.landingPage, brandName).trim();
  if (!query || query.length < 5) continue;
  const weight = deriveConversionWeight(attr.converted, attr.dealValue, attr.conversionType);
  const prev = weightMap.get(query);
  if (prev === undefined || weight > prev) weightMap.set(query, weight);
}

console.log("  FRAGMENT_SEEDED entries (vertical=healthcare, locale=national):");
for (const [query, weight] of weightMap) {
  console.log(`    query="${query}"  conversionWeight=${weight.toFixed(2)}`);
}

console.log("\n  CATEGORY_COVERAGE entries (vertical=healthcare, locale=national):");
const healthcareCategories = [
  "best primary care doctor near me",
  "how to find a good family physician",
  "primary care vs urgent care when to go",
  "what to look for in a primary care doctor",
  "how to get a same-day doctor appointment",
];
for (const q of healthcareCategories) {
  console.log(`    query="${q}"  conversionWeight=0.00  source=CATEGORY_COVERAGE`);
}

console.log("\n=== All checks passed ===\n");
