// Mock data for the contractor onboarding. The UI is fully interactive against
// these. The cheaper model replaces each with a real endpoint (see
// onboarding-agency-types.ts for the exact shapes) — DO NOT delete the types;
// only swap the data source.
//
// Vibn builds CUSTOM TOOLS for local businesses. The consultant picks the tool
// categories they want to build; we intersect those with each SMB type's
// `softwareNeeds` (market_data_assets/smb_to_software_mapping_final.json) to
// recommend local businesses they could target.

import type {
  CityRef,
  TerritoryOpportunity,
  ToolCategory,
} from "./onboarding-agency-types";

// ── Cities (DEV FALLBACK ONLY) ───────────────────────────────────────────────
// Production city lookup hits Places API (New) Autocomplete (global, 200M+
// places) via GET /api/agency/cities — see CityLookup, which calls that endpoint
// and only falls back to this list when offline.
export const STARTER_CITIES: CityRef[] = [
  {
    id: "victoria-bc",
    name: "Victoria",
    region: "BC",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "vancouver-bc",
    name: "Vancouver",
    region: "BC",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "nanaimo-bc",
    name: "Nanaimo",
    region: "BC",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "kelowna-bc",
    name: "Kelowna",
    region: "BC",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "calgary-ab",
    name: "Calgary",
    region: "AB",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "edmonton-ab",
    name: "Edmonton",
    region: "AB",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "toronto-on",
    name: "Toronto",
    region: "ON",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "ottawa-on",
    name: "Ottawa",
    region: "ON",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "montreal-qc",
    name: "Montreal",
    region: "QC",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "halifax-ns",
    name: "Halifax",
    region: "NS",
    country: "Canada",
    countryCode: "CA",
  },
  {
    id: "seattle-wa",
    name: "Seattle",
    region: "WA",
    country: "United States",
    countryCode: "US",
  },
  {
    id: "portland-or",
    name: "Portland",
    region: "OR",
    country: "United States",
    countryCode: "US",
  },
  {
    id: "san-francisco-ca",
    name: "San Francisco",
    region: "CA",
    country: "United States",
    countryCode: "US",
  },
  {
    id: "austin-tx",
    name: "Austin",
    region: "TX",
    country: "United States",
    countryCode: "US",
  },
  {
    id: "denver-co",
    name: "Denver",
    region: "CO",
    country: "United States",
    countryCode: "US",
  },
  {
    id: "chicago-il",
    name: "Chicago",
    region: "IL",
    country: "United States",
    countryCode: "US",
  },
  {
    id: "new-york-ny",
    name: "New York",
    region: "NY",
    country: "United States",
    countryCode: "US",
  },
  {
    id: "london-uk",
    name: "London",
    region: "England",
    country: "United Kingdom",
    countryCode: "GB",
  },
  {
    id: "sydney-au",
    name: "Sydney",
    region: "NSW",
    country: "Australia",
    countryCode: "AU",
  },
];

export const DEFAULT_CITY: CityRef = STARTER_CITIES[0];
export const cityLabel = (c: CityRef) => `${c.name}, ${c.region}`;

/** GET /api/agency/cities?q= — mock typeahead over the seed list. */
export function searchCities(query: string): CityRef[] {
  const q = query.trim().toLowerCase();
  if (!q) return STARTER_CITIES.slice(0, 8);
  return STARTER_CITIES.filter(
    (c) =>
      cityLabel(c).toLowerCase().includes(q) ||
      c.country.toLowerCase().includes(q),
  ).slice(0, 8);
}

// ── Tool categories the consultant can build ─────────────────────────────────
// GET /api/agency/tool-categories. `label` MUST match the strings in
// smb_to_software_mapping so the targeting intersection works. These are the
// common horizontal tools; the backend can expose the full ~524 from the mapping.
export const TOOL_CATEGORIES: ToolCategory[] = [
  {
    id: "reporting",
    label: "Reporting / Dashboard Software",
    short: "Reporting & dashboards",
    icon: "chart",
  },
  {
    id: "scheduling",
    label: "Appointment Scheduling Software",
    short: "Booking & scheduling",
    icon: "calendar",
  },
  { id: "crm", label: "CRM Software", short: "Customer CRM", icon: "users" },
  {
    id: "invoicing",
    label: "Invoicing & Payments Software",
    short: "Invoicing & payments",
    icon: "receipt",
  },
  {
    id: "billing",
    label: "Billing Software",
    short: "Billing",
    icon: "receipt",
  },
  {
    id: "inventory",
    label: "Inventory Management Software",
    short: "Inventory",
    icon: "box",
  },
  {
    id: "pos",
    label: "Retail POS System",
    short: "Point of sale",
    icon: "card",
  },
  {
    id: "ordering",
    label: "Online Ordering Software",
    short: "Online ordering",
    icon: "cart",
  },
  {
    id: "reservations",
    label: "Reservations & Online Bookings",
    short: "Reservations",
    icon: "calendar",
  },
  {
    id: "fsm",
    label: "Field Service Management (FSM)",
    short: "Field service / dispatch",
    icon: "clipboard",
  },
  {
    id: "staff",
    label: "Employee Scheduling Software",
    short: "Staff scheduling",
    icon: "users",
  },
  {
    id: "membership",
    label: "Membership Management Software",
    short: "Memberships",
    icon: "badge",
  },
  {
    id: "marketing",
    label: "Marketing Automation Software",
    short: "Marketing automation",
    icon: "megaphone",
  },
  {
    id: "accounting",
    label: "Accounting Software",
    short: "Accounting",
    icon: "chart",
  },
  {
    id: "orders",
    label: "Order Management Software",
    short: "Order management",
    icon: "clipboard",
  },
];

// ── SMB types + their software needs (sample from the mapping) ────────────────
// Real targeting reads the full smb_to_software_mapping; this is a grounded
// sample so the intersection responds to selections offline. Counts are mock.
type SmbTarget = {
  gcid: string;
  displayName: string;
  softwareNeeds: string[];
  businessCount: number;
  weakPct: number;
  claimed: number;
};

const SMB_TARGETS: SmbTarget[] = [
  {
    gcid: "gcid:dentist",
    displayName: "Dentists",
    businessCount: 312,
    weakPct: 0.71,
    claimed: 0,
    softwareNeeds: [
      "Dental Practice Management",
      "EHR / EMR Software",
      "Medical Billing Software",
      "Patient Scheduling Software",
      "Appointment Scheduling Software",
    ],
  },
  {
    gcid: "gcid:plumber",
    displayName: "Plumbers",
    businessCount: 287,
    weakPct: 0.86,
    claimed: 0,
    softwareNeeds: [
      "Plumbing Software",
      "Field Service Management (FSM)",
      "Scheduling Software",
      "Billing Software",
      "Invoicing & Payments Software",
    ],
  },
  {
    gcid: "gcid:hvac_contractor",
    displayName: "HVAC contractors",
    businessCount: 248,
    weakPct: 0.83,
    claimed: 1,
    softwareNeeds: [
      "HVAC Software",
      "Field Service Management (FSM)",
      "Accounting Software",
      "Invoicing & Payments Software",
    ],
  },
  {
    gcid: "gcid:hair_salon",
    displayName: "Hair salons",
    businessCount: 524,
    weakPct: 0.74,
    claimed: 6,
    softwareNeeds: [
      "Salon / Spa Management Software",
      "Appointment Scheduling Software",
      "Billing Software",
      "CRM Software",
    ],
  },
  {
    gcid: "gcid:beauty_salon",
    displayName: "Beauty salons",
    businessCount: 411,
    weakPct: 0.76,
    claimed: 3,
    softwareNeeds: [
      "Salon / Spa Management Software",
      "Appointment Scheduling Software",
      "CRM Software",
      "Retail POS System",
      "Accounting Software",
    ],
  },
  {
    gcid: "gcid:auto_repair_shop",
    displayName: "Auto repair shops",
    businessCount: 198,
    weakPct: 0.8,
    claimed: 1,
    softwareNeeds: [
      "Auto Repair Shop Software",
      "Invoicing & Payments Software",
      "Appointment Scheduling Software",
      "Inventory Management Software",
      "CRM Software",
    ],
  },
  {
    gcid: "gcid:gym",
    displayName: "Gyms & fitness studios",
    businessCount: 134,
    weakPct: 0.58,
    claimed: 2,
    softwareNeeds: [
      "Fitness & Gym Management Software",
      "Membership Management Software",
      "Appointment Scheduling Software",
      "Billing Software",
      "CRM Software",
    ],
  },
  {
    gcid: "gcid:restaurant",
    displayName: "Restaurants",
    businessCount: 642,
    weakPct: 0.69,
    claimed: 5,
    softwareNeeds: [
      "Restaurant POS Software",
      "Inventory Management Software",
      "Employee Scheduling Software",
      "Online Ordering Software",
    ],
  },
  {
    gcid: "gcid:medical_spa",
    displayName: "Med spas",
    businessCount: 96,
    weakPct: 0.62,
    claimed: 0,
    softwareNeeds: [
      "Medical Spa Software",
      "Appointment Scheduling Software",
      "CRM Software",
      "Retail POS System",
      "Marketing Automation Software",
    ],
  },
  {
    gcid: "gcid:electrician",
    displayName: "Electricians",
    businessCount: 233,
    weakPct: 0.82,
    claimed: 1,
    softwareNeeds: [
      "Electrical Contractor Software",
      "Field Service Management (FSM)",
      "Accounting Software",
      "Invoicing & Payments Software",
    ],
  },
  {
    gcid: "gcid:veterinarian",
    displayName: "Veterinarians",
    businessCount: 88,
    weakPct: 0.64,
    claimed: 0,
    softwareNeeds: [
      "Veterinary Management Software",
      "Appointment Scheduling Software",
      "Inventory Management Software",
      "Medical Billing Software",
    ],
  },
  {
    gcid: "gcid:coffee_shop",
    displayName: "Coffee shops",
    businessCount: 276,
    weakPct: 0.67,
    claimed: 4,
    softwareNeeds: [
      "Restaurant POS Software",
      "Inventory Management Software",
      "Employee Scheduling Software",
      "Marketing Automation Software",
      "Online Ordering Software",
    ],
  },
  {
    gcid: "gcid:florist",
    displayName: "Florists",
    businessCount: 109,
    weakPct: 0.78,
    claimed: 0,
    softwareNeeds: [
      "Florist Software",
      "Retail POS System",
      "Inventory Management Software",
      "Online Ordering Software",
      "Order Management Software",
    ],
  },
  {
    gcid: "gcid:landscaper",
    displayName: "Landscapers",
    businessCount: 264,
    weakPct: 0.85,
    claimed: 1,
    softwareNeeds: [
      "Landscape / Lawn Care Software",
      "Field Service Management (FSM)",
      "Appointment Scheduling Software",
      "Billing Software",
      "CRM Software",
    ],
  },
  {
    gcid: "gcid:accounting_firm",
    displayName: "Accounting firms",
    businessCount: 187,
    weakPct: 0.59,
    claimed: 2,
    softwareNeeds: [
      "Accounting Practice Management",
      "Accounting Software",
      "CRM Software",
    ],
  },
  {
    gcid: "gcid:bakery",
    displayName: "Bakeries",
    businessCount: 142,
    weakPct: 0.72,
    claimed: 0,
    softwareNeeds: [
      "Bakery Software",
      "Inventory Management Software",
      "Order Management Software",
      "Employee Scheduling Software",
    ],
  },
];

// ── AI expertise → tool categories ───────────────────────────────────────────
// POST /api/agency/analyze-expertise { text } -> { tools }. The real version is
// an LLM call; this is a keyword stub so the flow works offline. Maps free-text
// expertise to canonical tool-category labels that join to the SMB mapping.
const EXPERTISE_KEYWORDS: Array<{ re: RegExp; label: string }> = [
  {
    re: /report|dashboard|analytic|insight|\bbi\b/i,
    label: "Reporting / Dashboard Software",
  },
  {
    re: /crm|customer relationship|\bleads?\b|\bclients?\b/i,
    label: "CRM Software",
  },
  {
    re: /schedul|book|appointment|calendar/i,
    label: "Appointment Scheduling Software",
  },
  { re: /invoic|payment/i, label: "Invoicing & Payments Software" },
  { re: /billing/i, label: "Billing Software" },
  { re: /inventor|stock/i, label: "Inventory Management Software" },
  {
    re: /\bpos\b|point of sale|checkout|register/i,
    label: "Retail POS System",
  },
  { re: /online order|ordering|takeout/i, label: "Online Ordering Software" },
  { re: /reservation/i, label: "Reservations & Online Bookings" },
  {
    re: /field service|dispatch|\bfsm\b|work order/i,
    label: "Field Service Management (FSM)",
  },
  {
    re: /staff schedul|employee schedul|\brota\b|\bshifts?\b/i,
    label: "Employee Scheduling Software",
  },
  { re: /member/i, label: "Membership Management Software" },
  {
    re: /marketing|campaign|email automat|newsletter/i,
    label: "Marketing Automation Software",
  },
  { re: /account|bookkeep/i, label: "Accounting Software" },
  {
    re: /order management|fulfilment|fulfillment/i,
    label: "Order Management Software",
  },
];

export function extractTools(text: string): string[] {
  const out: string[] = [];
  for (const k of EXPERTISE_KEYWORDS) {
    if (k.re.test(text) && !out.includes(k.label)) out.push(k.label);
  }
  return out;
}

/**
 * POST /api/agency/targets { city, tools }
 * Recommends SMB types whose softwareNeeds intersect the consultant's tools,
 * scored by demand × gap × low Vibn saturation, biased toward how many of the
 * consultant's tools each SMB needs.
 */
export function mockTargets(
  city: CityRef,
  tools: string[],
): TerritoryOpportunity[] {
  const want = new Set(tools);
  // Reporting / dashboards apply to virtually every business, so treat it as a
  // universal need rather than listing it on every SMB type.
  const UNIVERSAL = ["Reporting / Dashboard Software"];
  return SMB_TARGETS.map((s, i) => {
    const needs = [
      ...s.softwareNeeds,
      ...UNIVERSAL.filter((u) => !s.softwareNeeds.includes(u)),
    ];
    const matchedTools = needs.filter((n) => want.has(n));
    return { s, matchedTools, i };
  })
    .filter((x) => x.matchedTools.length > 0)
    .map(({ s, matchedTools, i }) => {
      const weak = Math.round(s.businessCount * s.weakPct);
      const saturation = s.claimed / Math.max(1, s.businessCount / 20);
      const demand = s.weakPct * (1 - Math.min(1, saturation));
      const fit = Math.min(1, matchedTools.length / Math.max(1, tools.length));
      const score = Math.max(
        28,
        Math.min(98, Math.round((demand * 0.7 + fit * 0.3) * 100)),
      );
      const status: TerritoryOpportunity["status"] =
        s.claimed === 0 ? "open" : s.claimed <= 2 ? "contested" : "claimed";
      return {
        id: `${s.gcid}-${i}`,
        gcid: s.gcid,
        niche: s.displayName,
        city: city.name,
        businessCount: s.businessCount,
        weakWebsiteCount: weak,
        vibnClaimedCount: s.claimed,
        opportunityScore: score,
        status,
        matchedTools,
      };
    })
    .sort((a, b) => b.opportunityScore - a.opportunityScore);
}
