/**
 * Industry Classifier
 * ────────────────────
 * Haiku-powered industry classification that returns a rich IndustryContext
 * object used to frame synthesis prompts and drive targeted SERP queries.
 *
 * Internal module — model/provider names must not appear in user-facing contexts.
 */

import type { ContentSample } from "../scrapers/firecrawl-content";

const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY?.trim() ?? "";
const CLASSIFIER_MODEL = "claude-haiku-4-5-20251001";
const CLASSIFIER_MAX_TOKENS = 800;
const CLASSIFIER_TIMEOUT_MS = 30_000;

// ─── Exported types ───────────────────────────────────────────────────────────

export interface IndustryContext {
  industry: string;      // primary industry -- backward-compat alias for industries[0]
  industries: string[];  // all applicable industries, primary first; most brands have exactly one
  subVertical: string;
  audienceFraming: string;
  relevantFrameworks: string[];
  aiVisibilityBenchmark: string;  // e.g. "SMB healthcare typically sees 0.5-2% AI referral rate"
  schemaPriorities: string[];     // e.g. ["MedicalOrganization", "LocalBusiness", "FAQPage"]
  suggestedQueries: string[];     // 5-7 industry queries for SERP analysis
  conversionPathExpectation: string[]; // typical CTAs e.g. ["Book appointment", "Request consultation"]
}

// ─── Safe fallback ─────────────────────────────────────────────────────────────

function buildFallback(industry: string): IndustryContext {
  return {
    industry,
    industries: [industry],
    subVertical: "general",
    audienceFraming: "Prospective customers searching for products or services online.",
    relevantFrameworks: ["E-E-A-T", "Technical SEO", "Content Quality"],
    aiVisibilityBenchmark: "SMB businesses typically see 0.5-2% AI referral rate of total organic sessions.",
    schemaPriorities: ["Organization", "WebSite", "FAQPage"],
    suggestedQueries: [],
    conversionPathExpectation: ["Contact us", "Get a quote", "Request information"],
  };
}

// ─── Haiku classification call ────────────────────────────────────────────────

/**
 * Classifies a brand's industry using Haiku and returns a rich IndustryContext.
 * On parse failure or API error, returns a safe fallback with the inferred industry string.
 */
export async function classifyIndustry(
  brandName: string,
  website: string,
  contentSamples: ContentSample[],
): Promise<IndustryContext> {
  if (!ANTHROPIC_API_KEY) return buildFallback("other");

  const homepageMarkdown =
    contentSamples.find((s) => {
      try {
        const u = new URL(s.url);
        return u.pathname === "/" || u.pathname === "";
      } catch {
        return false;
      }
    })?.markdown ??
    contentSamples[0]?.markdown ??
    "";

  const userMsg = `Brand name: ${brandName}
Website: ${website}
Homepage content (first 1200 characters):
${homepageMarkdown.slice(0, 1200)}

Classify this business and return a JSON object with these exact fields:
{
  "industries": ["primary industry first, then any secondary industries. Each value must be one of: higher-ed, healthcare-medical, healthcare-dental, healthcare-mental-health, healthcare-veterinary, healthcare-other, b2b-saas, b2b-services, b2b-manufacturing, b2b-finance, b2b-legal, b2b-other, ecommerce-fashion, ecommerce-beauty, ecommerce-electronics, ecommerce-home, ecommerce-food, ecommerce-pet, ecommerce-other, ecommerce, local-services, professional-services, finance, legal, real-estate, nonprofit, hospitality, other. Most brands have exactly one industry — only add secondary industries when the brand legitimately serves two distinct verticals (e.g. a B2B SaaS product built specifically for healthcare practices). The primary industry (first in the array) MUST be the dominant business focus that would be returned in single-industry mode. Return at most 3 industries."],
  "subVertical": "specific niche within the primary industry (e.g. cardiology-practice, personal-injury-law, hvac-contractor)",
  "audienceFraming": "one sentence: who is searching for this brand and what outcome do they want",
  "relevantFrameworks": ["3-4 SEO/marketing frameworks most applicable, e.g. E-E-A-T, YMYL, local-pack, product-schema"],
  "aiVisibilityBenchmark": "one sentence benchmarking typical AI referral rates for this industry/size segment",
  "schemaPriorities": ["3-5 schema.org types most important for this business, ordered by priority"],
  "suggestedQueries": ["5-7 Google search queries a prospective customer would use to find this type of business, no brand name"],
  "conversionPathExpectation": ["2-4 typical CTAs or conversion actions for this industry, e.g. Book appointment"]
}`;

  try {
    const res = await fetch("https://api.anthropic.com/v1/messages", {
      method: "POST",
      signal: AbortSignal.timeout(CLASSIFIER_TIMEOUT_MS),
      headers: {
        "x-api-key": ANTHROPIC_API_KEY,
        "anthropic-version": "2023-06-01",
        "content-type": "application/json",
      },
      body: JSON.stringify({
        model: CLASSIFIER_MODEL,
        max_tokens: CLASSIFIER_MAX_TOKENS,
        temperature: 0,
        system:
          "You classify businesses by industry and produce structured JSON for SEO audit framing. Return only valid JSON, no markdown fences, no preamble.",
        messages: [{ role: "user", content: userMsg }],
      }),
    });

    if (!res.ok) {
      console.warn(`[audit-industry] classifyIndustry HTTP ${res.status} — using fallback`);
      return buildFallback("other");
    }

    const data = (await res.json()) as {
      content: Array<{ type: string; text: string }>;
    };

    const raw = (data.content.find((c) => c.type === "text")?.text ?? "").trim();

    // Strip markdown fences if present
    const cleaned = raw
      .replace(/^```(?:json)?\n?/m, "")
      .replace(/\n?```$/m, "")
      .trim();

    let parsed: Partial<IndustryContext>;
    try {
      parsed = JSON.parse(cleaned) as Partial<IndustryContext>;
    } catch {
      console.warn(`[audit-industry] classifyIndustry JSON parse failed — using fallback`);
      return buildFallback("other");
    }

    // Validate required fields and build a safe result
    const VALID_INDUSTRIES = [
      "higher-ed",
      "healthcare-medical", "healthcare-dental", "healthcare-mental-health",
      "healthcare-veterinary", "healthcare-other",
      "b2b-saas", "b2b-services", "b2b-manufacturing", "b2b-finance",
      "b2b-legal", "b2b-other",
      "ecommerce-fashion", "ecommerce-beauty", "ecommerce-electronics",
      "ecommerce-home", "ecommerce-food", "ecommerce-pet", "ecommerce-other",
      "ecommerce", "local-services", "professional-services", "finance",
      "legal", "real-estate", "nonprofit", "hospitality", "other",
    ] as const;

    const validSet = VALID_INDUSTRIES as readonly string[];

    function sanitizeIndustry(raw: unknown): string {
      const s = typeof raw === "string" ? raw.trim().toLowerCase() : "";
      return validSet.includes(s) ? s : "other";
    }

    // Defensive dual-format parsing: handle both new (industries[]) and old (industry string) responses.
    let industries: string[];
    const parsedAny = parsed as Record<string, unknown>;

    if (Array.isArray(parsedAny.industries) && parsedAny.industries.length > 0) {
      // New format: industries array
      industries = (parsedAny.industries as unknown[]).map(sanitizeIndustry).slice(0, 3);
      if (industries.length === 0) industries = ["other"];

      // If model also returned legacy industry field, verify they agree on primary
      if (typeof parsedAny.industry === "string") {
        const legacyPrimary = sanitizeIndustry(parsedAny.industry);
        if (legacyPrimary !== "other" && legacyPrimary !== industries[0]) {
          console.warn(`[audit-industry] classifyIndustry: industries[0]=${industries[0]} disagrees with legacy industry=${legacyPrimary} — trusting industries[0]`);
        }
      }
    } else if (typeof parsedAny.industry === "string") {
      // Model regressed to old single-industry format
      industries = [sanitizeIndustry(parsedAny.industry)];
    } else {
      industries = ["other"];
    }

    const industry = industries[0]!;

    const result: IndustryContext = {
      industry,
      industries,
      subVertical: typeof parsed.subVertical === "string" && parsed.subVertical ? parsed.subVertical : "general",
      audienceFraming: typeof parsed.audienceFraming === "string" && parsed.audienceFraming ? parsed.audienceFraming : buildFallback(industry).audienceFraming,
      relevantFrameworks: Array.isArray(parsed.relevantFrameworks) ? parsed.relevantFrameworks.map(String).slice(0, 5) : buildFallback(industry).relevantFrameworks,
      aiVisibilityBenchmark: typeof parsed.aiVisibilityBenchmark === "string" && parsed.aiVisibilityBenchmark ? parsed.aiVisibilityBenchmark : buildFallback(industry).aiVisibilityBenchmark,
      schemaPriorities: Array.isArray(parsed.schemaPriorities) ? parsed.schemaPriorities.map(String).slice(0, 6) : buildFallback(industry).schemaPriorities,
      suggestedQueries: Array.isArray(parsed.suggestedQueries) ? parsed.suggestedQueries.map(String).slice(0, 7) : [],
      conversionPathExpectation: Array.isArray(parsed.conversionPathExpectation) ? parsed.conversionPathExpectation.map(String).slice(0, 5) : buildFallback(industry).conversionPathExpectation,
    };

    console.log(`[audit-industry] classifyIndustry ${brandName} → industries=${industries.join(",")} subVertical=${result.subVertical} queries=${result.suggestedQueries.length} schemaPriorities=${result.schemaPriorities.join(",")}`);
    return result;
  } catch (err) {
    console.warn(
      `[audit-industry] classifyIndustry failed (non-fatal):`,
      err instanceof Error ? err.message : err,
    );
    return buildFallback("other");
  }
}
