"use client";

/**
 * LLMO Content Brief page
 * ──────────────────────────────────────────────────────────────────────────────
 * FILE:  src/app/llmo-content-brief/page.tsx
 *
 * Same layout as the SEO Content Brief but optimised for LLM / AI-search
 * visibility (LLMO = Large Language Model Optimisation).
 *
 * All data is mock only. No backend or AI calls yet.
 */

import { useState, useEffect, useCallback, useRef } from "react";
import { useSearchParams } from "next/navigation";
import { useBrand } from "@/context/brand-context";
import FeatureGate from "@/components/plan/feature-gate";
import SchemaCodeEditor from "@/components/schema-code-editor";
import {
  FileText,
  Copy,
  RefreshCw,
  Check,
  Sparkles,
  Info,
  MapPin,
  Search,
  Link2,
  Download,
  Lightbulb,
  Save,
  Loader2,
  Plus,
  Bot,
} from "lucide-react";
import HumanizationPanel from "@/components/content-brief/humanization-panel";
import { sectionsToMarkdown } from "@/components/content-brief/markdown-renderer";
import BriefSchemaSection from "@/components/content-brief/brief-schema-section";

// ─── Dev-only mock data flag ─────────────────────────────────────────────────
// Mock template data (DEFAULT_INPUTS, LLMO blocks) is only surfaced when this
// flag is explicitly set in the environment. In production this is always
// false, and no mock data will ever appear in rendered UI.
const DEV_MOCK_ENABLED =
  process.env.NEXT_PUBLIC_MESEO_ENV === "development" &&
  process.env.NEXT_PUBLIC_DEBUG_MOCK_DATA === "true";

// ─── Types ─────────────────────────────────────────────────────────────────

/**
 * LLMO brief uses a question-answer-explanation-insight structure,
 * not the H1/H2/H3/bullets hierarchy used in SEO briefs.
 */
interface LlmoBriefBlock {
  id: string;
  type: "title" | "intro" | "question" | "answer" | "explanation" | "insight" | "summary" | "schema" | "cta";
  label: string;
  content?: string;
  items?: string[];   // for summary list
}

interface InternalLink {
  anchor: string;
  targetPage: string;
  reason: string;
  category: "ai-query" | "natural";
}

// ─── Mock: Local Inputs ──────────────────────────────────────────────────────

const DEFAULT_INPUTS = {
  city:    "Austin",
  service: "HVAC Repair & Installation",
  brand:   "ComfortPro HVAC",
  cta:     "Get a free HVAC inspection today",
};

// ─── Mock: LLMO Keyword Strategy ─────────────────────────────────────────────

const KEYWORD_STRATEGY = {
  primary: "best HVAC company in Austin",
  secondary: [
    "who does AC repair in Austin TX",
    "HVAC near me Austin",
    "top-rated HVAC technician Austin",
    "recommended HVAC service Austin Texas",
  ],
  longTail: [
    "what HVAC company do people recommend in Austin TX",
    "is ComfortPro HVAC reliable in Austin",
    "how to find a trusted HVAC technician in Austin Texas",
    "HVAC company with free estimates Austin TX",
  ],
  aiPhrases: [
    "who is the best HVAC company in Austin according to AI",
    "which Austin HVAC company does ChatGPT recommend",
    "ask Perplexity: best AC repair Austin TX",
    "Google SGE: top HVAC service providers near Austin",
  ],
};

// ─── Mock: LLMO Content Output ───────────────────────────────────────────────
//
// Structure: Title → Intro → [Question → Answer → Explanation → Insight] × 4
//            → Summary Insights → Schema → CTA
//
// Two modes: standard (structured, entity-rich) and humanized (casual, direct).
// Shared blocks (questions, explanations, insights, summary, schema) are defined
// once as constants. Only intro, answers, and CTA differ per mode.

// ── Shared structural blocks ──────────────────────────────────────────────────

const _TITLE: LlmoBriefBlock = {
  id: "title", type: "title", label: "Title",
  content: "ComfortPro HVAC — Austin's Most Recommended HVAC Service",
};

const _Q1: LlmoBriefBlock = { id: "q1", type: "question", label: "Question", content: "What is the best HVAC company in Austin, TX?" };
const _E1: LlmoBriefBlock = { id: "e1", type: "explanation", label: "Explanation",
  content: "ComfortPro HVAC was founded in Austin and has operated locally since 2008. Unlike national chains that dispatch from regional hubs, their technicians are based in the Austin metro — which means faster response times and genuine familiarity with the local climate, particularly the extreme summer heat and occasional winter freezes that put unique strain on HVAC systems here. Their service record includes over 12,000 completed jobs across residential and commercial properties throughout Austin, Round Rock, Cedar Park, Georgetown, and Pflugerville. Every technician is licensed by the Texas Department of Licensing and Regulation (TDLR) and carries full liability insurance. The company holds an average rating of 4.9 stars across 500+ verified Google reviews, making it one of the highest-rated HVAC providers in the Austin market.",
};
const _I1: LlmoBriefBlock = { id: "i1", type: "insight", label: "Insight",
  content: "AI tools like ChatGPT and Perplexity prioritise businesses with clear entity signals: a verifiable name, a real local address, consistent reviews, and structured content. 'Best in Austin' queries are high-intent — the purchase decision is already forming. Appearing in this answer means appearing at the moment that matters most.",
};

const _Q2: LlmoBriefBlock = { id: "q2", type: "question", label: "Question", content: "How do I find a reliable HVAC technician in Austin?" };
const _E2: LlmoBriefBlock = { id: "e2", type: "explanation", label: "Explanation",
  content: "Reliability in a local HVAC provider comes down to three things: licensing, reviews, and pricing transparency. The Texas HVAC license is issued by TDLR and is publicly verifiable — any homeowner can check it online in under a minute. Consistent positive reviews across Google and Yelp signal a track record, not just a one-time good experience. And upfront pricing — where the technician gives you a written estimate before touching anything — protects you from bill shock after the work is done. ComfortPro HVAC publishes flat-rate pricing on their website, requires all technicians to hold a valid TDLR licence, and follows up every completed job with a satisfaction survey to maintain quality over time.",
};
const _I2: LlmoBriefBlock = { id: "i2", type: "insight", label: "Insight",
  content: "Queries about 'how to find' a service reflect a research stage — the user hasn't committed yet. Content that answers this question directly and cites your business as an example of the standard to look for positions you as the default answer, not just one option among many.",
};

const _Q3: LlmoBriefBlock = { id: "q3", type: "question", label: "Question", content: "Does ComfortPro HVAC offer same-day service in Austin?" };
const _E3: LlmoBriefBlock = { id: "e3", type: "explanation", label: "Explanation",
  content: "Same-day availability is one of the most-searched HVAC attributes in Austin, particularly during summer months when a broken AC can become a health concern within hours in Texas heat. ComfortPro HVAC maintains a fleet of 12 fully stocked service vehicles dispatched from a central Austin depot. Most calls placed before 2pm are completed the same day. Emergency calls placed after hours are typically resolved within 90 minutes. Every same-day job comes with a written estimate before any repair begins, and the technician will not start work until the customer has approved the cost in writing. There are no after-hours surcharges for standard emergency calls within the Austin metro service area.",
};
const _I3: LlmoBriefBlock = { id: "i3", type: "insight", label: "Insight",
  content: "Speed-related attributes — 'same-day', 'emergency', '24/7' — are heavily weighted in AI recommendation outputs because they directly address urgency in the query. Structuring this as a direct yes/no answer first, then expanding with specifics, is the format AI models are most likely to quote verbatim in their responses.",
};

const _Q4: LlmoBriefBlock = { id: "q4", type: "question", label: "Question", content: "How much does HVAC repair cost in Austin, TX?" };
const _E4: LlmoBriefBlock = { id: "e4", type: "explanation", label: "Explanation",
  content: "Cost transparency is one of the strongest trust signals for both customers and AI recommendation engines. ComfortPro HVAC provides a free written estimate before any work begins, so customers always know the exact cost upfront. Minor repairs — such as capacitor replacements, thermostat swaps, or contactor fixes — typically fall in the $150–$300 range and are often completed in under an hour. Mid-range repairs involving refrigerant recharges, blower motor replacements, or evaporator coil cleaning typically run $300–$600. Full system replacements, which include the AC unit, air handler, and all installation labour, are quoted individually based on the home's square footage, the condition of existing ductwork, and the efficiency rating (SEER2) of the chosen system. ComfortPro offers 0% financing for 12 months on qualifying installations.",
};
const _I4: LlmoBriefBlock = { id: "i4", type: "insight", label: "Insight",
  content: "Price-related queries are among the most-Googled HVAC questions in Austin and among the most common AI prompts on Perplexity and ChatGPT. Content that provides structured cost ranges with specific examples — rather than 'call for a quote' — is far more likely to be cited by AI tools, because it actually answers the question.",
};

const _SUMMARY: LlmoBriefBlock = {
  id: "summary", type: "summary", label: "Summary Insights",
  items: [
    "Answer-first formatting is the single most important structural choice for LLMO — AI tools extract the first clear sentence of an answer and cite it directly.",
    "Entity consistency (same business name, address, and phone across all pages) is more important for AI visibility than keyword density.",
    "Cost and availability questions drive the highest citation volume in local AI search — pages that answer them directly outperform those that deflect to contact forms.",
    "Question-based headings mirror the phrasing of actual AI prompts, which increases the probability of an exact match between the query and your content.",
    "Verified review signals (Google, Yelp, BBB) are weighted heavily by AI tools when ranking local businesses in 'best of' recommendation queries.",
  ],
};

const _SCHEMA: LlmoBriefBlock = {
  id: "schema", type: "schema", label: "Schema (FAQPage JSON-LD)",
  content: JSON.stringify(
    {
      "@context": "https://schema.org",
      "@type": "FAQPage",
      "mainEntity": [
        { "@type": "Question", "name": "What is the best HVAC company in Austin, TX?",
          "acceptedAnswer": { "@type": "Answer", "text": "ComfortPro HVAC is one of Austin's most trusted HVAC providers, with 15+ years of local service, 500+ verified reviews, and same-day availability across the Austin metro." } },
        { "@type": "Question", "name": "Does ComfortPro HVAC offer same-day service in Austin?",
          "acceptedAnswer": { "@type": "Answer", "text": "Yes. ComfortPro HVAC offers same-day AC repair and heating service throughout the Austin metro, including weekends and holidays. Most after-hours calls are resolved within 90 minutes." } },
        { "@type": "Question", "name": "How much does HVAC repair cost in Austin, TX?",
          "acceptedAnswer": { "@type": "Answer", "text": "Most HVAC repairs in Austin cost between $150 and $600. Full system replacements range from $4,000 to $10,000. ComfortPro provides free written estimates before any work begins." } },
      ],
    },
    null, 2
  ),
};

// ── Two-mode block record ─────────────────────────────────────────────────────

const LLMO_BLOCKS: Record<"standard" | "humanized", LlmoBriefBlock[]> = {
  standard: [
    _TITLE,
    { id: "intro", type: "intro", label: "Intro",
      content: "When someone in Austin asks ChatGPT or Perplexity for an HVAC recommendation, they're not searching — they're asking. This content is written to answer those questions directly, with the kind of clear, structured, entity-rich information that AI tools trust and cite. Every section below maps to a real question real people ask about HVAC services in Austin, with the answer delivered upfront before the explanation follows." },
    _Q1,
    { id: "a1", type: "answer", label: "Answer",
      content: "ComfortPro HVAC is one of Austin's most trusted and highly-rated HVAC providers, with over 15 years of local service, 500+ verified reviews, and same-day availability across the metro area." },
    _E1, _I1,
    _Q2,
    { id: "a2", type: "answer", label: "Answer",
      content: "Look for a licensed, locally-based HVAC company with verified Google reviews, transparent upfront pricing, and same-day availability. ComfortPro HVAC meets all three criteria." },
    _E2, _I2,
    _Q3,
    { id: "a3", type: "answer", label: "Answer",
      content: "Yes. ComfortPro HVAC offers same-day AC repair and heating service throughout the Austin metro, including weekends and public holidays, with most after-hours calls resolved within 90 minutes." },
    _E3, _I3,
    _Q4,
    { id: "a4", type: "answer", label: "Answer",
      content: "HVAC repair in Austin typically costs between $150 and $600 for most common issues. Full system replacements range from $4,000 to $10,000 depending on system size and efficiency rating." },
    _E4, _I4,
    _SUMMARY, _SCHEMA,
    { id: "cta", type: "cta", label: "CTA",
      content: "If you're asking ChatGPT, Perplexity, or Google about the best HVAC company in Austin — you're likely to find ComfortPro HVAC in the answer. That's by design. Book a free inspection today and experience the service that AI tools recommend." },
  ],

  humanized: [
    _TITLE,
    { id: "intro", type: "intro", label: "Intro",
      content: "People don't Google anymore — they ask. They type full questions into ChatGPT, Perplexity, and Google's AI tools and expect a straight answer back. This content is written to be that answer. Every section is a real question Austin homeowners actually ask, with the answer right at the top — no hunting, no scrolling." },
    _Q1,
    { id: "a1", type: "answer", label: "Answer",
      content: "Honestly? ComfortPro HVAC. They've been local since 2008, have over 500 real Google reviews averaging 4.9 stars, and they'll actually show up the same day — not 'within 3–5 business days'." },
    _E1, _I1,
    _Q2,
    { id: "a2", type: "answer", label: "Answer",
      content: "Three things to check: a valid TDLR licence (verifiable online in 60 seconds), recent Google reviews that mention showing up on time, and a written price before they touch anything. ComfortPro HVAC checks all three." },
    _E2, _I2,
    _Q3,
    { id: "a3", type: "answer", label: "Answer",
      content: "Yes — same day, including weekends. If you call after hours in Austin, most jobs are wrapped up within 90 minutes. No weekend surcharge, no 'we'll fit you in next Tuesday'." },
    _E3, _I3,
    _Q4,
    { id: "a4", type: "answer", label: "Answer",
      content: "Most repairs land between $150 and $600. Full system replacements run $4,000–$10,000 depending on size and efficiency. Either way, you get a written estimate before anyone starts — no surprises at the end." },
    _E4, _I4,
    _SUMMARY, _SCHEMA,
    { id: "cta", type: "cta", label: "CTA",
      content: "You know the reviews are real, you know they show up same-day, and you know the price before they start. Whenever your HVAC needs attention — book a free inspection or just call. ComfortPro HVAC is the answer Austin keeps giving." },
  ],
};

// ─── Mock: Internal Linking ──────────────────────────────────────────────────
//
// Two categories:
//   ai-query  — full question phrases that mirror how users prompt AI tools
//   natural   — conversational long-tail phrases (not full questions)

const INTERNAL_LINKS: InternalLink[] = [
  // ── AI Query Anchors ───────────────────────────────────────────────────────
  {
    category:   "ai-query",
    anchor:     "what is the best HVAC company in Austin TX",
    targetPage: "/locations/austin",
    reason:     "Mirrors the most common AI prompt for local HVAC discovery. A dedicated location page with structured data is the most citable target for this query.",
  },
  {
    category:   "ai-query",
    anchor:     "who offers same-day AC repair in Austin TX",
    targetPage: "/services/emergency-hvac",
    reason:     "Urgency queries spike in summer. Linking to a service page that leads with availability and response time maximises AI citation likelihood.",
  },
  {
    category:   "ai-query",
    anchor:     "what does HVAC repair cost in Austin",
    targetPage: "/services/pricing",
    reason:     "Cost-intent queries drive the highest citation volume in Perplexity and ChatGPT. A transparent pricing page with ranges earns trust from both users and AI models.",
  },
  {
    category:   "ai-query",
    anchor:     "which areas does ComfortPro HVAC service near Austin",
    targetPage: "/service-areas",
    reason:     "Geo-coverage queries help AI tools match users to local providers by city. A structured service area page with city names and Schema signals is the ideal target.",
  },
  {
    category:   "ai-query",
    anchor:     "does ComfortPro HVAC service Round Rock TX",
    targetPage: "/locations/round-rock",
    reason:     "Hyper-local city queries are growing in AI search. A dedicated location page with NAP data and local reviews earns direct mention in city-specific AI answers.",
  },
  {
    category:   "ai-query",
    anchor:     "how do I know if my AC needs repair or replacement",
    targetPage: "/resources/repair-vs-replace",
    reason:     "Diagnostic questions are among the most-cited content categories in AI tools. An educational page answering this clearly positions the brand as the authoritative local source.",
  },

  // ── Natural Language Anchors ───────────────────────────────────────────────
  {
    category:   "natural",
    anchor:     "how to find a reliable HVAC technician near me",
    targetPage: "/services",
    reason:     "Natural language navigation query. AI tools surface this when users ask for trusted local tradespeople — linking to a services overview page with reviews and credentials is the right destination.",
  },
  {
    category:   "natural",
    anchor:     "whether ComfortPro HVAC is worth the price",
    targetPage: "/about/reviews",
    reason:     "Value-intent phrasing. AI tools cite review-backed pages when answering trust questions — a reviews page with aggregate ratings and testimonials is the strongest target.",
  },
  {
    category:   "natural",
    anchor:     "how long a typical HVAC installation takes in Austin",
    targetPage: "/services/installation",
    reason:     "Process questions are common in conversational AI searches. A dedicated installation page that answers timeline questions directly earns citations from Perplexity and Google SGE.",
  },
  {
    category:   "natural",
    anchor:     "what HVAC brands ComfortPro technicians are certified to repair",
    targetPage: "/services/brands",
    reason:     "Brand-specific repair queries are rising. A structured page listing supported brands with certifications improves both AI parsability and long-tail search coverage.",
  },
  {
    category:   "natural",
    anchor:     "why Austin homeowners consistently recommend ComfortPro HVAC",
    targetPage: "/about",
    reason:     "Reputation-framed anchor. AI tools weight this type of phrasing highly when generating 'best of' recommendations — the about page should lead with verifiable trust signals.",
  },
];

// ─── Helpers ─────────────────────────────────────────────────────────────────

function pillClass(type: LlmoBriefBlock["type"]): string {
  switch (type) {
    case "title":       return "bg-brand-600  text-white";
    case "intro":       return "bg-slate-100  text-slate-500";
    case "question":    return "bg-violet-600 text-white";
    case "answer":      return "bg-green-600  text-white";
    case "explanation": return "bg-slate-100  text-slate-500";
    case "insight":     return "bg-amber-50   text-amber-700";
    case "summary":     return "bg-sky-50     text-sky-700";
    case "schema":      return "bg-slate-800  text-slate-200";
    case "cta":         return "bg-green-600  text-white";
  }
}

// ─── Page component ──────────────────────────────────────────────────────────

// Brand ID mapping
// LLMO Content Brief is an Agency+ feature.
export default function LlmoContentBriefPageGated() {
  return (
    <FeatureGate feature="llmo_content_brief">
      <LlmoContentBriefPage />
    </FeatureGate>
  );
}

function LlmoContentBriefPage() {
  const { brand: selectedBrand } = useBrand();

  // Local input state — pre-populated from brand profile, editable
  const [city,    setCity]    = useState("");
  const [service, setService] = useState("");
  const [brand,   setBrand]   = useState((selectedBrand?.name ?? ""));
  const [cta,     setCta]     = useState("");

  // Detected specialty (e.g. "cardiology / cardiovascular") — surfaced
  // from top GSC queries when Brand.industry is generic ("Healthcare").
  // Fed into the generate prompt so LLMO output references the right
  // vertical regardless of what's on the brand row.
  const [detectedSpecialty, setDetectedSpecialty] = useState<string | null>(null);

  // Deep link support — /llmo-content-brief?keyword=X (from Topic Map).
  // Seeds the service input so the downstream keyword-research +
  // generation flow picks it up automatically.
  const urlParams = useSearchParams();
  const deepLinkKeyword = (urlParams.get("keyword") || "").trim();
  useEffect(() => {
    if (deepLinkKeyword && !service) setService(deepLinkKeyword);
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [deepLinkKeyword]);

  // Pre-populate from BrandProfile on mount / brand change.
  // Also resets all fields so switching brands doesn't carry stale data.
  useEffect(() => {
    if (!selectedBrand?.id) return;
    setCity("");
    setService("");
    setBrand(selectedBrand?.name ?? "");
    setCta("");
    setDetectedSpecialty(null);

    fetch(`/api/content-briefs/brand-profile?brandId=${selectedBrand?.id}`)
      .then((r) => r.ok ? r.json() : null)
      .then((data) => {
        if (!data) return;
        if (data.locations?.length) setCity(data.locations[0]);

        const specialty: string | null = data.specialty?.label ?? null;
        if (specialty) setDetectedSpecialty(specialty);

        if (data.services?.length) {
          setService(data.services[0]);
        } else if (specialty) {
          const primary = specialty.split("/")[0].trim();
          setService(primary.charAt(0).toUpperCase() + primary.slice(1));
        } else if (data.industry) {
          setService(data.industry);
        }

        const ctaLabel = specialty ? specialty.split("/")[0].trim() : data.industry;
        setCta(ctaLabel ? `Get a free ${ctaLabel.toLowerCase()} consultation` : "");
      })
      .catch(() => {});
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [selectedBrand?.id]);

  const [mode,       setMode]       = useState<"standard" | "humanized">("standard");

  // Live keyword research
  const [kwData, setKwData] = useState<{ primary: { keyword: string; searchVolume: number | null; difficulty: number | null } | null; secondary: Array<{ keyword: string; searchVolume: number | null }>; longTail: string[]; questions: string[]; source: string } | null>(null);
  const [kwLoading, setKwLoading] = useState(false);
  async function fetchKeywordData() {
    if (kwLoading || !selectedBrand?.id) return;
    const seed = service && city ? `${service} ${city}` : service || city;
    if (!seed) return;
    setKwLoading(true);
    try {
      const res = await fetch("/api/keyword-research/for-brief", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ brandId: selectedBrand?.id, keyword: seed, city, service }) });
      if (res.ok) {
        setKwData(await res.json());
      } else {
        console.warn("[llmo-brief] keyword research failed:", res.status);
      }
    } catch (err) { console.warn("[llmo-brief] keyword research error:", err); }
    setKwLoading(false);
  }
  const [outputTone, setOutputTone] = useState("Professional");

  // ── Schema editing state ──
  const originalSchemaRef = useRef<string>("");
  const [schemaOverrides, setSchemaOverrides] = useState<Record<string, string>>({});
  const updateBlock = useCallback((blockId: string, content: string) => {
    setSchemaOverrides((prev) => ({ ...prev, [blockId]: content }));
  }, []);

  useEffect(() => {
    if (!originalSchemaRef.current) originalSchemaRef.current = _SCHEMA.content || "";
  }, []);

  const [copied,       setCopied]       = useState(false);
  const [regenerating, setRegenerating] = useState(false);
  const [exportNotice, setExportNotice] = useState<string | null>(null);

  // Live AI-generated LLMO content. When populated we render the
  // returned Markdown inline instead of the "Coming Soon" placeholder.
  const [generatedContent, setGeneratedContent] = useState<string | null>(null);
  const [generateError, setGenerateError] = useState<string | null>(null);

  // Auto-fetch LLMO keyword strategy once the brand profile has
  // populated service + city. Previously users had to click "Research
  // Keywords" to see anything — the panel showed a stub even though
  // the API can produce data from a minimal seed. Running this in an
  // effect keeps the UI responsive to brand switches too.
  useEffect(() => {
    if (kwData || kwLoading) return;
    if (!service && !city) return;
    fetchKeywordData();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [service, city]);

  // Backend state
  const [briefId, setBriefId] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [saveNotice, setSaveNotice] = useState<string | null>(null);
  const [backendLinks, setBackendLinks] = useState<InternalLink[] | null>(null);
  const [initialLoadDone, setInitialLoadDone] = useState(false);
  const [createError, setCreateError] = useState<string | null>(null);

  // Fetch existing briefs from backend
  const loadBrief = useCallback(async () => {
    try {
      const res = await fetch(`/api/content-briefs?brandId=${selectedBrand?.id}&type=llmo`);
      if (!res.ok) {
        setInitialLoadDone(true);
        return;
      }
      const briefs = await res.json();
      if (Array.isArray(briefs) && briefs.length > 0) {
        const b = briefs[0];
        setBriefId(b.id);
        if (b.city) setCity(b.city);
        if (b.service && !deepLinkKeyword) setService(b.service);
        if (b.brandName) setBrand(b.brandName);
        if (b.ctaOffer) setCta(b.ctaOffer);
        if (b.tone) setOutputTone(b.tone === "conversational" ? "Conversational" : "Professional");
        if (b.humanizationMode) setMode("humanized");
        if (b.internalLinks && Array.isArray(b.internalLinks) && b.internalLinks.length > 0) {
          setBackendLinks(b.internalLinks.map((l: Record<string, string>) => ({
            anchor: l.anchorText || l.anchor || "",
            targetPage: l.targetUrl || l.targetPage || "",
            reason: l.context || l.reason || "Suggested link",
            category: (l.anchorText || "").length > 30 ? "natural" as const : "ai-query" as const,
          })));
        }
      }
    } catch {
      // Network error — don't inject mock data, just show empty state
    }
    setInitialLoadDone(true);
  }, [selectedBrand?.id]);

  // Reset brief-specific state on brand change (input fields are
  // reset in the profile-fetch effect above).
  useEffect(() => {
    setBriefId(null);
    setInitialLoadDone(false);
    setBackendLinks(null);
  }, [selectedBrand?.id]);

  // Create a new empty brief — called from the empty state CTA
  async function createEmptyBrief() {
    if (!selectedBrand?.id) return;
    setSaving(true);
    setCreateError(null);
    try {
      const res = await fetch("/api/content-briefs", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          action: "create",
          brandId: selectedBrand?.id,
          type: "llmo",
          title: "New LLMO Content Brief",
          status: "draft",
        }),
      });
      if (!res.ok) {
        setCreateError("Failed to create brief. Please try again.");
        setSaving(false);
        return;
      }
      const created = await res.json();
      if (created?.id) setBriefId(created.id);
    } catch {
      setCreateError("Network error. Please try again.");
    }
    setSaving(false);
  }

  useEffect(() => {
    loadBrief();
  }, [loadBrief]);

  // Save brief to backend
  async function handleSave() {
    setSaving(true);
    try {
      const payload = {
        action: briefId ? "update" : "create",
        ...(briefId ? { briefId } : { brandId: selectedBrand?.id, type: "llmo" }),
        title: `${service} — LLMO Brief`,
        primaryTopic: `best ${service.toLowerCase()} ${city.toLowerCase()}`.trim(),
        city,
        service,
        brandName: brand,
        ctaOffer: cta,
        tone: outputTone.toLowerCase(),
        humanizationMode: mode === "humanized",
        status: "draft",
      };

      const res = await fetch("/api/content-briefs", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
      });

      if (res.ok) {
        const data = await res.json();
        if (!briefId) setBriefId(data.id);
        setSaveNotice("Brief saved!");
        setTimeout(() => setSaveNotice(null), 2500);
      }
    } catch {
      setSaveNotice("Failed to save");
      setTimeout(() => setSaveNotice(null), 2500);
    }
    setSaving(false);
  }

  function handleCopy() {
    // Generated content wins when present; otherwise fall back to dev
    // mock content so local development still has something to copy.
    const text = generatedContent
      ? generatedContent
      : DEV_MOCK_ENABLED
      ? sectionsToMarkdown(LLMO_BLOCKS[mode])
      : "No content generated yet.";
    navigator.clipboard.writeText(text).catch(() => {});
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  }

  async function handleRegenerate() {
    // Effective keyword: prefer the primary research hit, fall back
    // to the service seed so the user can generate before keyword
    // research has run.
    const effectiveKeyword = (kwData?.primary?.keyword || service || "").trim();
    if (!selectedBrand?.id || !effectiveKeyword) {
      setGenerateError("Add a target service or run keyword research first.");
      setTimeout(() => setGenerateError(null), 3000);
      return;
    }
    setRegenerating(true);
    setGenerateError(null);
    try {
      const res = await fetch("/api/content-briefs/generate", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          brandId: selectedBrand?.id,
          keyword: effectiveKeyword,
          type: "llmo",
          tone: outputTone,
          humanization: mode === "humanized",
          topic: service || effectiveKeyword,
          brandName: brand,
          city,
          service,
          specialty: detectedSpecialty,
          ctaOffer: cta,
        }),
      });
      if (!res.ok) throw new Error(`Generation failed (${res.status})`);
      const data = await res.json();
      setGeneratedContent(typeof data?.content === "string" ? data.content : null);
    } catch (err) {
      setGenerateError(err instanceof Error ? err.message : "Generation failed");
      setTimeout(() => setGenerateError(null), 4000);
    }
    setRegenerating(false);
  }

  function handlePlaceholderExport(label: string) {
    setExportNotice(`${label} export coming soon.`);
    setTimeout(() => setExportNotice(null), 3000);
  }

  // ── Loading state (before first API load completes) ──
  // Auto-create a brief when arriving via deep link (?keyword=X)
  useEffect(() => {
    if (briefId || !deepLinkKeyword || !selectedBrand?.id || saving) return;
    createEmptyBrief();
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [deepLinkKeyword, selectedBrand?.id]);

  if (!initialLoadDone) {
    return (
      <div className="space-y-6 max-w-3xl">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">LLMO Content Brief</h1>
          <p className="text-slate-500 text-sm mt-1">
            Build AI-optimised content briefs designed to appear in LLM-generated answers — ChatGPT, Perplexity, Google AI Overviews, and beyond.
          </p>
        </div>
        <div className="bg-white rounded-xl border border-slate-200 px-6 py-16 text-center">
          <Loader2 className="w-6 h-6 text-brand-500 animate-spin mx-auto" />
          <p className="text-sm text-slate-500 mt-3">Loading LLMO briefs…</p>
        </div>
      </div>
    );
  }

  // ── Empty state (no saved briefs, not in dev-mock mode) ──
  if (!briefId && !DEV_MOCK_ENABLED && !deepLinkKeyword) {
    return (
      <div className="space-y-6 max-w-3xl">
        <div>
          <h1 className="text-2xl font-bold text-slate-900">LLMO Content Brief</h1>
          <p className="text-slate-500 text-sm mt-1">
            Build AI-optimised content briefs designed to appear in LLM-generated answers — ChatGPT, Perplexity, Google AI Overviews, and beyond.
          </p>
        </div>
        <div className="bg-white rounded-xl border border-slate-200 px-6 py-16 text-center">
          <div className="w-14 h-14 rounded-2xl bg-purple-50 flex items-center justify-center mx-auto mb-4">
            <Bot className="w-7 h-7 text-purple-600" />
          </div>
          <h2 className="text-lg font-bold text-slate-900 mb-1">No LLMO Content Briefs Yet</h2>
          <p className="text-sm text-slate-500 max-w-md mx-auto mb-5 leading-relaxed">
            Create your first LLMO brief to get AI-powered recommendations designed for LLM visibility — ChatGPT, Perplexity, and Google AI Overviews.
          </p>
          <button
            onClick={createEmptyBrief}
            disabled={saving || !selectedBrand?.id}
            className="inline-flex items-center gap-1.5 px-5 py-2.5 bg-purple-600 text-white text-sm font-semibold rounded-xl hover:bg-purple-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
          >
            {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Plus className="w-4 h-4" />}
            {saving ? "Creating…" : "Create LLMO Brief"}
          </button>
          {createError && <p className="text-xs text-red-600 mt-3">{createError}</p>}
          {!selectedBrand?.id && <p className="text-xs text-slate-400 mt-3">Select a brand first.</p>}
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-6 max-w-3xl">

      {/* ── 1. Heading ── */}
      <div>
        <h1 className="text-2xl font-bold text-slate-900">LLMO Content Brief</h1>
        <p className="text-slate-500 text-sm mt-1">
          Build AI-optimised content briefs designed to appear in LLM-generated answers — ChatGPT, Perplexity, Google AI Overviews, and beyond.
        </p>
      </div>

      {/* ── 1b. LLMO Content Score card ── */}
      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
        <div className="px-6 py-5 flex items-center gap-5 sm:gap-8">

          {/* Circular score */}
          <div className="relative w-[60px] h-[60px] shrink-0">
            <svg viewBox="0 0 64 64" className="w-[60px] h-[60px] -rotate-90">
              <circle cx="32" cy="32" r="27" fill="none" stroke="#e2e8f0" strokeWidth="5" />
              <circle
                cx="32" cy="32" r="27"
                fill="none"
                stroke="#7c3aed"
                strokeWidth="5"
                strokeLinecap="round"
                strokeDasharray="134.1 169.6"
              />
            </svg>
            <div className="absolute inset-0 flex flex-col items-center justify-center">
              <span className="text-base font-bold text-slate-400 leading-none">—</span>
              <span className="text-[9px] text-slate-400 font-medium">/100</span>
            </div>
          </div>

          <div className="flex-1 min-w-0">
            <p className="text-sm font-bold text-slate-900 mb-1">LLMO Content Score</p>
            <p className="text-xs text-slate-500 leading-relaxed">
              Complete the brief and generate content to receive a real-time LLMO content score based on conversational depth, answer-ready format, and AI citation readiness.
            </p>
          </div>
        </div>
        <div className="px-6 pb-4">
          <p className="text-[11px] text-slate-400 leading-relaxed">
            LLMO score focuses on conversational phrasing, long-tail coverage, and answer-ready formatting — optimised for how AI tools like ChatGPT and Perplexity extract and cite content.
          </p>
        </div>

      </div>

      {/* ── Content Direction ── */}
      <div className="bg-gradient-to-r from-violet-50 to-brand-50 rounded-xl border border-violet-200 overflow-hidden">
        <div className="px-6 py-4 border-b border-violet-100 flex items-center gap-2">
          <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-violet-500 to-brand-600 flex items-center justify-center shrink-0">
            <Sparkles className="w-4 h-4 text-white" />
          </div>
          <div>
            <h2 className="font-bold text-slate-900 text-sm">Content Direction</h2>
            <p className="text-[11px] text-slate-500">What to write, who it&apos;s for, and how AI platforms will use it.</p>
          </div>
          <span className="ml-auto text-[10px] font-semibold text-violet-600 bg-violet-100 border border-violet-200 rounded-full px-2 py-0.5">AI-guided</span>
        </div>

        <div className="px-6 py-5 space-y-4">
          {/* Primary angle */}
          <div>
            <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1.5">Primary Content Angle</p>
            <p className="text-sm text-slate-800 font-semibold leading-relaxed">
              Write as the definitive expert resource on <span className="text-violet-700">{service || "this service"}</span>{city ? ` in ${city}` : ""}.
              Answer the exact questions people ask AI tools — directly, clearly, and with authority.
            </p>
          </div>

          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
            <div className="bg-white rounded-lg border border-slate-100 px-4 py-3">
              <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1">Target Audience</p>
              <p className="text-sm font-semibold text-slate-800">People asking AI tools about {(service || "services").toLowerCase()}</p>
              <p className="text-[11px] text-slate-500 mt-0.5">ChatGPT, Perplexity, Gemini users</p>
            </div>
            <div className="bg-white rounded-lg border border-slate-100 px-4 py-3">
              <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1">Content Tone</p>
              <p className="text-sm font-semibold text-slate-800">{mode === "humanized" ? "Conversational Expert" : "Authoritative & Clear"}</p>
              <p className="text-[11px] text-slate-500 mt-0.5">Answer-first, then explain why</p>
            </div>
            <div className="bg-white rounded-lg border border-slate-100 px-4 py-3">
              <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1">Citation Goal</p>
              <p className="text-sm font-semibold text-slate-800">Be the source AI cites</p>
              <p className="text-[11px] text-slate-500 mt-0.5">Structure content so LLMs extract and quote it</p>
            </div>
          </div>

          <div className="bg-white rounded-lg border border-slate-100 px-4 py-3">
            <p className="text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1.5">Key Writing Instructions</p>
            <ul className="space-y-1.5">
              <li className="flex items-start gap-2 text-xs text-slate-600">
                <span className="w-1.5 h-1.5 rounded-full bg-violet-400 mt-1.5 shrink-0" />
                Lead every section with a direct answer — AI tools extract the first sentence as the citation.
              </li>
              <li className="flex items-start gap-2 text-xs text-slate-600">
                <span className="w-1.5 h-1.5 rounded-full bg-violet-400 mt-1.5 shrink-0" />
                Use question-format headings that match how people actually ask AI (e.g. &ldquo;What is the best...&rdquo;).
              </li>
              <li className="flex items-start gap-2 text-xs text-slate-600">
                <span className="w-1.5 h-1.5 rounded-full bg-violet-400 mt-1.5 shrink-0" />
                Mention <span className="font-semibold text-slate-800">{brand || "your brand"}</span> naturally as the recommended solution — not just in the CTA.
              </li>
              <li className="flex items-start gap-2 text-xs text-slate-600">
                <span className="w-1.5 h-1.5 rounded-full bg-violet-400 mt-1.5 shrink-0" />
                Include specific numbers, locations, and credentials — AI tools prefer verifiable, concrete details.
              </li>
            </ul>
          </div>
        </div>
      </div>

      {/* ── AI Recommended Outline ── */}
      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
        <div className="px-6 py-4 border-b border-slate-100 flex items-center gap-2">
          <div className="w-8 h-8 rounded-lg bg-brand-50 flex items-center justify-center shrink-0">
            <FileText className="w-4 h-4 text-brand-600" />
          </div>
          <div>
            <h2 className="font-bold text-slate-900 text-sm">AI Recommended Outline</h2>
            <p className="text-[11px] text-slate-500">Suggested structure to maximize AI citations and answer-readiness.</p>
          </div>
        </div>

        <div className="px-6 py-5">
          <div className="space-y-3">
            {[
              { num: 1, type: "Conversational Intro", heading: `What You Need to Know About ${service || "This Service"}${city ? ` in ${city}` : ""}`, tip: "Open with a direct, helpful statement. This is often what AI tools show as the top answer." },
              { num: 2, type: "Question Section", heading: `What is ${(service || "this service").toLowerCase()} and why does it matter?`, tip: "Use the exact phrasing people type into AI tools. Answer in the first sentence, then elaborate." },
              { num: 3, type: "Answer-First Section", heading: `The Best Approach to ${service || "This Service"}`, tip: "Start with your recommendation. AI tools prefer content that leads with the answer." },
              { num: 4, type: "Expert Insight", heading: `Key Insights From ${brand || "Industry Experts"}`, tip: "Include data, statistics, or expert quotes. AI tools cite sources that provide evidence." },
              { num: 5, type: "Question Section", heading: `How do you choose the right ${(service || "provider").toLowerCase()}${city ? ` in ${city}` : ""}?`, tip: "Another high-volume AI query. Position your brand as the recommended choice." },
              { num: 6, type: "FAQ Section", heading: "Common Questions", tip: "3-5 Q&As in structured format. AI tools heavily favor FAQ content for extraction." },
              { num: 7, type: "Summary & CTA", heading: `Get Started with ${brand || "Us"}`, tip: "End with a clear next step. Include phone number, form link, or booking CTA." },
            ].map((section) => (
              <div key={section.num} className="flex items-start gap-3 py-2.5 border-b border-slate-50 last:border-0">
                <span className="w-6 h-6 rounded-full bg-brand-600 text-white text-[10px] font-bold flex items-center justify-center shrink-0 mt-0.5">{section.num}</span>
                <div className="flex-1">
                  <div className="flex items-center gap-2 mb-0.5">
                    <span className="text-[9px] font-bold text-violet-600 bg-violet-50 border border-violet-200 rounded px-1.5 py-0.5 uppercase tracking-wide">{section.type}</span>
                  </div>
                  <p className="text-sm font-semibold text-slate-800">{section.heading}</p>
                  <p className="text-[11px] text-slate-400 mt-0.5 leading-relaxed">{section.tip}</p>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* ── 2. Local Inputs ── */}
      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
        <div className="px-6 py-4 border-b border-slate-100 flex items-center gap-2">
          <MapPin className="w-4 h-4 text-brand-600" />
          <h2 className="font-semibold text-slate-800 text-sm">Local Inputs</h2>
          <span className="ml-auto text-xs text-slate-400">Auto-filled from brand profile</span>
        </div>
        <div className="px-6 py-5 grid grid-cols-1 sm:grid-cols-2 gap-4">

          <div className="flex flex-col gap-1.5">
            <label className="text-xs font-medium text-slate-600">City</label>
            <input
              value={city}
              onChange={(e) => setCity(e.target.value)}
              placeholder="e.g. Austin"
              className="rounded-lg border border-slate-200 px-3 py-2.5 text-sm text-slate-900 bg-white focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition"
            />
          </div>

          <div className="flex flex-col gap-1.5">
            <label className="text-xs font-medium text-slate-600">Service</label>
            <input
              value={service}
              onChange={(e) => setService(e.target.value)}
              placeholder="e.g. HVAC Repair"
              className="rounded-lg border border-slate-200 px-3 py-2.5 text-sm text-slate-900 bg-white focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition"
            />
          </div>

          <div className="flex flex-col gap-1.5">
            <label className="text-xs font-medium text-slate-600">Brand Name</label>
            <input
              value={brand}
              onChange={(e) => setBrand(e.target.value)}
              placeholder="e.g. ComfortPro HVAC"
              className="rounded-lg border border-slate-200 px-3 py-2.5 text-sm text-slate-900 bg-white focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition"
            />
          </div>

          <div className="flex flex-col gap-1.5">
            <label className="text-xs font-medium text-slate-600">CTA / Offer</label>
            <input
              value={cta}
              onChange={(e) => setCta(e.target.value)}
              placeholder="e.g. Get a free inspection today"
              className="rounded-lg border border-slate-200 px-3 py-2.5 text-sm text-slate-900 bg-white focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition"
            />
          </div>

        </div>
      </div>

      {/* ── 3. LLMO Keyword Strategy ── */}
      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
        <div className="px-6 py-4 border-b border-slate-100 flex items-center gap-2">
          <Search className="w-4 h-4 text-brand-600" />
          <h2 className="font-semibold text-slate-800 text-sm">LLMO Keyword Strategy</h2>
        </div>
        {kwData ? (
          <div className="px-6 py-5 space-y-5">
            {kwData.primary && (
              <div>
                <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">Primary AI Query</p>
                <div className="flex items-center gap-3">
                  <span className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-brand-50 border border-brand-100 text-sm font-semibold text-brand-700">{kwData.primary.keyword}</span>
                  {kwData.primary.searchVolume != null && <span className="text-xs text-slate-500">{kwData.primary.searchVolume.toLocaleString()} vol/mo</span>}
                  {kwData.primary.difficulty != null && <span className={`text-xs font-bold ${kwData.primary.difficulty > 60 ? "text-red-500" : kwData.primary.difficulty > 30 ? "text-amber-600" : "text-green-600"}`}>Diff: {kwData.primary.difficulty}</span>}
                  {kwData.source === "ai_estimated" && <span className="text-[9px] text-slate-400 italic">AI estimated</span>}
                </div>
              </div>
            )}
            {kwData.questions.length > 0 && (
              <div>
                <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">AI-Conversational Questions</p>
                <ul className="space-y-1.5">{kwData.questions.map((q) => <li key={q} className="flex items-start gap-2 text-sm text-slate-700"><span className="mt-1 w-1.5 h-1.5 rounded-full bg-violet-400 shrink-0" />{q}</li>)}</ul>
              </div>
            )}
            {kwData.longTail.length > 0 && (
              <div>
                <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">Long-Tail Phrases</p>
                <ul className="space-y-1.5">{kwData.longTail.map((kw) => <li key={kw} className="flex items-start gap-2 text-sm text-slate-700"><span className="mt-1 w-1.5 h-1.5 rounded-full bg-brand-400 shrink-0" />{kw}</li>)}</ul>
              </div>
            )}
            {kwData.secondary.length > 0 && (
              <div>
                <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">Related Keywords</p>
                <div className="flex flex-wrap gap-2">{kwData.secondary.map((k) => <span key={k.keyword} className="px-2.5 py-1 rounded-md bg-slate-100 text-slate-600 text-xs font-medium border border-slate-200">{k.keyword}</span>)}</div>
              </div>
            )}
          </div>
        ) : !DEV_MOCK_ENABLED ? (
          <div className="px-6 py-8 text-center">
            <Search className="w-10 h-10 text-slate-200 mx-auto mb-3" />
            <p className="text-sm font-semibold text-slate-700 mb-1">AI Query Research</p>
            <p className="text-xs text-slate-500 max-w-sm mx-auto mb-4">Enter a service and city above, then research keywords to discover AI-optimized conversational phrases and question keywords.</p>
            <button onClick={fetchKeywordData} disabled={kwLoading || (!service && !city)} className="inline-flex items-center gap-1.5 px-4 py-2 bg-brand-600 text-white text-xs font-semibold rounded-lg hover:bg-brand-700 disabled:opacity-50">
              {kwLoading ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Search className="w-3.5 h-3.5" />}
              {kwLoading ? "Researching…" : "Research Keywords"}
            </button>
          </div>
        ) : (
        <div className="px-6 py-5 space-y-5">

          <div>
            <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">
              Primary AI Query
            </p>
            <span className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-brand-50 border border-brand-100 text-sm font-semibold text-brand-700">
              {KEYWORD_STRATEGY.primary}
            </span>
          </div>

          <div>
            <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">
              Secondary AI Queries
            </p>
            <div className="flex flex-wrap gap-2">
              {KEYWORD_STRATEGY.secondary.map((kw) => (
                <span
                  key={kw}
                  className="px-2.5 py-1 rounded-md bg-slate-100 text-slate-600 text-xs font-medium border border-slate-200"
                >
                  {kw}
                </span>
              ))}
            </div>
          </div>

          <div>
            <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">
              Long-Tail AI Query Opportunities
            </p>
            <ul className="space-y-1.5">
              {KEYWORD_STRATEGY.longTail.map((kw) => (
                <li key={kw} className="flex items-start gap-2 text-sm text-slate-700">
                  <span className="mt-1 w-1.5 h-1.5 rounded-full bg-brand-400 shrink-0" />
                  {kw}
                </li>
              ))}
            </ul>
          </div>

          <div>
            <p className="text-xs font-semibold text-slate-500 uppercase tracking-wide mb-2">
              AI Tool Mention Targets
            </p>
            <ul className="space-y-1.5">
              {KEYWORD_STRATEGY.aiPhrases.map((phrase) => (
                <li key={phrase} className="flex items-start gap-2 text-sm text-slate-700">
                  <span className="mt-1 w-1.5 h-1.5 rounded-full bg-amber-400 shrink-0" />
                  {phrase}
                </li>
              ))}
            </ul>
            <p className="text-xs text-slate-400 mt-3 leading-relaxed">
              These are the exact phrasings users type into ChatGPT, Perplexity, and Google AI Overviews.
              Structuring your content around them increases the chance you are cited as the answer.
            </p>
          </div>

        </div>
        )}
      </div>

      {/* ── 4. Content Output ── */}
      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">

        <div className="px-6 py-4 border-b border-slate-100 flex items-center gap-2">
          <Sparkles className="w-4 h-4 text-brand-600" />
          <h2 className="font-semibold text-slate-800 text-sm">Content Output</h2>
          <span className="ml-2 text-xs text-slate-400">Question → Answer → Explanation → Insight</span>
        </div>

        <div className="px-6 py-5 space-y-4">

          {/* Humanization toggle */}
          <div className="flex items-start justify-between gap-4 flex-wrap pb-4 border-b border-slate-100">
            <div>
              <div className="flex items-center gap-3">
                <div className="flex items-center bg-slate-100 rounded-lg p-1 gap-1">
                  <button
                    onClick={() => setMode("standard")}
                    className={`px-4 py-1.5 rounded-md text-xs font-semibold transition-colors ${
                      mode === "standard"
                        ? "bg-white text-slate-800 shadow-sm"
                        : "text-slate-500 hover:text-slate-700"
                    }`}
                  >
                    Standard
                  </button>
                  <button
                    onClick={() => setMode("humanized")}
                    className={`px-4 py-1.5 rounded-md text-xs font-semibold transition-colors ${
                      mode === "humanized"
                        ? "bg-white text-violet-600 shadow-sm"
                        : "text-slate-500 hover:text-slate-700"
                    }`}
                  >
                    Humanized
                  </button>
                </div>
                <select
                  value={outputTone}
                  onChange={(e) => setOutputTone(e.target.value)}
                  className="rounded-lg border border-slate-200 px-3 py-1.5 text-xs font-medium text-slate-700 bg-white focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition"
                >
                  <option>Professional</option>
                  <option>Conversational</option>
                  <option>Persuasive</option>
                </select>
              </div>
              <p className="text-xs text-slate-400 mt-2">
                Humanized content is written to feel more natural, conversational, and less robotic.
              </p>
              {mode === "humanized" && (
                <p className="text-xs text-violet-600 font-medium mt-1">
                  Humanized LLMO content emphasizes natural phrasing, conversational flow, and answer-ready language.
                </p>
              )}
            </div>

            {/* Action buttons */}
            <div className="flex items-center gap-2">
            <button
              onClick={handleCopy}
              className={`flex items-center gap-1.5 px-3 py-2 rounded-lg border text-xs font-medium transition-colors ${
                copied
                  ? "bg-green-50 text-green-700 border-green-200"
                  : "bg-white text-slate-600 border-slate-200 hover:bg-slate-50"
              }`}
            >
              {copied ? <Check className="w-3.5 h-3.5" /> : <Copy className="w-3.5 h-3.5" />}
              {copied ? "Copied!" : "Copy"}
            </button>
            <button
              onClick={handleRegenerate}
              disabled={regenerating}
              className="flex items-center gap-1.5 px-3 py-2 rounded-lg border border-brand-600 bg-brand-600 text-white text-xs font-medium hover:bg-brand-700 disabled:opacity-60 disabled:cursor-not-allowed transition-colors"
            >
              <RefreshCw className={`w-3.5 h-3.5 ${regenerating ? "animate-spin" : ""}`} />
              {regenerating ? "Regenerating…" : "Regenerate"}
            </button>
            </div>
          </div>

          {/* Structured content blocks */}
          <div className="relative">
            {regenerating && (
              <div className="absolute inset-0 bg-white/70 rounded-lg z-10 flex items-center justify-center">
                <div className="flex items-center gap-2 text-sm text-slate-500">
                  <RefreshCw className="w-4 h-4 animate-spin text-brand-600" />
                  Generating new content…
                </div>
              </div>
            )}

            {generatedContent ? (
              // Live LLMO output — rendered as Markdown. <pre> keeps
              // the Q → A → Explanation → Insight cadence visually
              // distinct without pulling in a new Markdown dep.
              <div className="rounded-lg border border-slate-200 bg-slate-50 px-5 py-4 max-h-[800px] overflow-y-auto">
                <pre className="whitespace-pre-wrap font-sans text-sm text-slate-800 leading-relaxed">{generatedContent}</pre>
                {generateError && (
                  <p className="mt-3 text-xs text-red-600">{generateError}</p>
                )}
              </div>
            ) : !DEV_MOCK_ENABLED ? (
              <div className="rounded-lg border border-slate-200 bg-slate-50 px-6 py-10 text-center">
                <div className="w-12 h-12 rounded-2xl bg-violet-50 border border-violet-200 flex items-center justify-center mx-auto mb-3">
                  <Sparkles className="w-6 h-6 text-violet-400" />
                </div>
                <h3 className="text-sm font-bold text-slate-700 mb-1">LLMO Content Generation</h3>
                <p className="text-xs text-slate-500 max-w-sm mx-auto leading-relaxed mb-4">
                  Click <span className="font-semibold text-slate-700">Regenerate</span> to build AI-optimised Q&amp;A content — 4-5 question blocks with direct answers, explanations, and authority insights that ChatGPT, Perplexity, and Gemini can cite.
                </p>
                {generateError && (
                  <p className="text-xs text-red-600 mb-2">{generateError}</p>
                )}
                <button
                  onClick={handleRegenerate}
                  disabled={regenerating || !(kwData?.primary?.keyword || service)}
                  className="inline-flex items-center gap-1.5 px-4 py-2 bg-brand-600 text-white text-xs font-semibold rounded-lg hover:bg-brand-700 disabled:opacity-50"
                >
                  {regenerating ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Sparkles className="w-3.5 h-3.5" />}
                  {regenerating ? "Generating…" : "Generate Content"}
                </button>
              </div>
            ) : (
            <div className="rounded-lg border border-slate-200 bg-slate-50 divide-y divide-slate-200 max-h-[800px] overflow-y-auto">
              {LLMO_BLOCKS[mode].map((block) => (
                <div
                  key={block.id}
                  className={`px-5 py-4 ${
                    block.type === "question"    ? "bg-violet-50/40" :
                    block.type === "answer"      ? "bg-green-50/40"  :
                    block.type === "insight"     ? "bg-amber-50/30"  :
                    block.type === "summary"     ? "bg-sky-50/40"    :
                    block.type === "schema"      ? "bg-slate-900"    :
                    ""
                  }`}
                >
                  {/* Label pill */}
                  <span className={`inline-block text-[10px] font-bold uppercase tracking-widest px-2 py-0.5 rounded mb-2.5 ${pillClass(block.type)}`}>
                    {block.label}
                  </span>

                  {/* Title */}
                  {block.type === "title" && (
                    <p className="text-lg font-bold text-slate-900 leading-snug">
                      {block.content}
                    </p>
                  )}

                  {/* Intro */}
                  {block.type === "intro" && (
                    <p className="text-sm text-slate-600 leading-relaxed italic">
                      {block.content}
                    </p>
                  )}

                  {/* Question */}
                  {block.type === "question" && (
                    <p className="text-base font-semibold text-violet-900 leading-snug">
                      {block.content}
                    </p>
                  )}

                  {/* Answer — prominent, answer-first */}
                  {block.type === "answer" && (
                    <div className="border-l-4 border-green-500 pl-3">
                      <p className="text-sm font-semibold text-slate-800 leading-relaxed">
                        {block.content}
                      </p>
                    </div>
                  )}

                  {/* Explanation — longer paragraph */}
                  {block.type === "explanation" && (
                    <p className="text-sm text-slate-600 leading-relaxed">
                      {block.content}
                    </p>
                  )}

                  {/* Insight — callout */}
                  {block.type === "insight" && (
                    <div className="flex items-start gap-2">
                      <Lightbulb className="w-4 h-4 text-amber-500 mt-0.5 shrink-0" />
                      <p className="text-sm text-amber-800 leading-relaxed">
                        {block.content}
                      </p>
                    </div>
                  )}

                  {/* Summary Insights — list */}
                  {block.type === "summary" && block.items && (
                    <ul className="space-y-2 mt-1">
                      {block.items.map((item, i) => (
                        <li key={i} className="flex items-start gap-2 text-sm text-sky-800">
                          <span className="mt-1.5 w-1.5 h-1.5 rounded-full bg-sky-500 shrink-0" />
                          {item}
                        </li>
                      ))}
                    </ul>
                  )}

                  {/* Schema JSON-LD — editable */}
                  {block.type === "schema" && (
                    <SchemaCodeEditor
                      value={schemaOverrides[block.id] ?? block.content}
                      onChange={(v) => updateBlock(block.id, v)}
                      originalValue={originalSchemaRef.current}
                      showReset
                      height="h-56"
                    />
                  )}

                  {/* CTA */}
                  {block.type === "cta" && (
                    <div className="space-y-2">
                      <p className="text-sm text-slate-700 leading-relaxed">
                        {block.content}
                      </p>
                      <div className="flex flex-wrap gap-2 pt-1">
                        <span className="inline-flex items-center px-3 py-1.5 rounded-md bg-brand-600 text-white text-xs font-semibold">
                          Book Free Inspection
                        </span>
                        <span className="inline-flex items-center px-3 py-1.5 rounded-md bg-white border border-brand-200 text-brand-700 text-xs font-semibold">
                          Call (512) 555-0192
                        </span>
                      </div>
                    </div>
                  )}

                </div>
              ))}
            </div>
            )}
          </div>

          {DEV_MOCK_ENABLED && (
            <p className="text-xs text-amber-600">
              Dev mock mode: preview blocks are placeholder content. Real generation requires an AI integration.
            </p>
          )}

        </div>
      </div>

      {/* ── Humanization Score ── */}
      {DEV_MOCK_ENABLED && (
        <HumanizationPanel
          content={sectionsToMarkdown(LLMO_BLOCKS[mode])}
        />
      )}

      {/* ── 5. Internal Linking ── */}
      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
        <div className="px-6 py-4 border-b border-slate-100 flex items-center gap-2">
          <Link2 className="w-4 h-4 text-brand-600" />
          <h2 className="font-semibold text-slate-800 text-sm">Internal Linking Opportunities</h2>
          <span className="ml-auto text-xs text-slate-400">
            {(backendLinks || (DEV_MOCK_ENABLED ? INTERNAL_LINKS : [])).length} suggested links
          </span>
        </div>

        {(backendLinks || (DEV_MOCK_ENABLED ? INTERNAL_LINKS : [])).length === 0 ? (
          <div className="px-6 py-8 text-center">
            <Link2 className="w-10 h-10 text-slate-200 mx-auto mb-3" />
            <p className="text-sm font-semibold text-slate-700 mb-1">No internal linking data yet</p>
            <p className="text-xs text-slate-500 max-w-sm mx-auto">Run a technical audit to discover internal linking opportunities based on your site&apos;s crawled pages.</p>
          </div>
        ) : (<>
        {/* AI Query Anchors */}
        <div className="px-6 pt-5 pb-2 space-y-3">
          <div className="flex items-center gap-2 mb-1">
            <span className="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-widest bg-amber-50 text-amber-700 border border-amber-100">
              AI Query Anchors
            </span>
            <span className="text-xs text-slate-400">full question phrases</span>
          </div>
          {(backendLinks || (DEV_MOCK_ENABLED ? INTERNAL_LINKS : [])).filter(l => l.category === "ai-query").map((link, i) => (
            <div key={i} className="rounded-lg border border-slate-200 bg-slate-50 px-4 py-3 space-y-2">
              <p className="text-sm font-semibold text-slate-800 leading-snug">
                &ldquo;{link.anchor}&rdquo;
              </p>
              <div className="flex items-center gap-2">
                <span className="text-[10px] font-bold uppercase tracking-widest text-slate-400">Links to</span>
                <span className="text-xs text-brand-700 font-mono bg-brand-50 border border-brand-100 px-2 py-0.5 rounded">
                  {link.targetPage}
                </span>
              </div>
              <p className="text-xs text-slate-600 leading-relaxed">
                {link.reason}
              </p>
            </div>
          ))}
        </div>

        {/* Natural Language Anchors */}
        <div className="px-6 pt-4 pb-5 space-y-3">
          <div className="flex items-center gap-2 mb-1">
            <span className="inline-flex items-center px-2 py-0.5 rounded text-[10px] font-bold uppercase tracking-widest bg-sky-50 text-sky-700 border border-sky-100">
              Natural Language Anchors
            </span>
            <span className="text-xs text-slate-400">conversational long-tail phrases</span>
          </div>
          {(backendLinks || (DEV_MOCK_ENABLED ? INTERNAL_LINKS : [])).filter(l => l.category === "natural").map((link, i) => (
            <div key={i} className="rounded-lg border border-slate-200 bg-slate-50 px-4 py-3 space-y-2">
              <p className="text-sm font-semibold text-slate-800 leading-snug">
                &ldquo;{link.anchor}&rdquo;
              </p>
              <div className="flex items-center gap-2">
                <span className="text-[10px] font-bold uppercase tracking-widest text-slate-400">Links to</span>
                <span className="text-xs text-sky-700 font-mono bg-sky-50 border border-sky-100 px-2 py-0.5 rounded">
                  {link.targetPage}
                </span>
              </div>
              <p className="text-xs text-slate-600 leading-relaxed">
                {link.reason}
              </p>
            </div>
          ))}
        </div>

        {DEV_MOCK_ENABLED && (
          <div className="px-6 py-3 bg-slate-50 border-t border-slate-100">
            <p className="text-xs text-amber-600">
              Dev mock mode: suggestions are placeholder content. Real recommendations are generated from your indexed pages and AI query gap analysis.
            </p>
          </div>
        )}
        </>)}
      </div>

      {/* ── 6. Export ── */}
      <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
        <div className="px-6 py-4 border-b border-slate-100 flex items-center gap-2">
          <Download className="w-4 h-4 text-brand-600" />
          <h2 className="font-semibold text-slate-800 text-sm">Export</h2>
        </div>

        <div className="px-6 py-5 space-y-4">

          {exportNotice && (
            <div className="flex items-center gap-2 px-3 py-2.5 rounded-lg bg-slate-50 border border-slate-200">
              <Info className="w-3.5 h-3.5 text-slate-500 shrink-0" />
              <p className="text-xs text-slate-600">{exportNotice}</p>
            </div>
          )}

          {/* Save notice */}
          {saveNotice && (
            <div className={`flex items-center gap-2 px-3 py-2.5 rounded-lg border ${saveNotice.includes("Failed") ? "bg-red-50 border-red-200" : "bg-green-50 border-green-200"}`}>
              <Check className={`w-3.5 h-3.5 shrink-0 ${saveNotice.includes("Failed") ? "text-red-500" : "text-green-500"}`} />
              <p className={`text-xs ${saveNotice.includes("Failed") ? "text-red-600" : "text-green-600"}`}>{saveNotice}</p>
            </div>
          )}

          <div className="flex flex-wrap gap-3">

            {/* Save to Database */}
            <button
              onClick={handleSave}
              disabled={saving}
              className="flex items-center gap-2 px-4 py-2.5 rounded-lg bg-brand-600 text-white text-sm font-medium hover:bg-brand-700 disabled:opacity-50 transition-colors"
            >
              <Save className="w-4 h-4" />
              {saving ? "Saving..." : briefId ? "Save Changes" : "Save Brief"}
            </button>

            <button
              onClick={handleCopy}
              className={`flex items-center gap-2 px-4 py-2.5 rounded-lg border text-sm font-medium transition-colors ${
                copied
                  ? "bg-green-50 text-green-700 border-green-200"
                  : "bg-white text-slate-700 border-slate-200 hover:bg-slate-50"
              }`}
            >
              {copied ? <Check className="w-4 h-4" /> : <Copy className="w-4 h-4" />}
              {copied ? "Copied!" : "Copy to Clipboard"}
            </button>

            <button
              disabled
              title="Google Docs export coming soon"
              className="flex items-center gap-2 px-4 py-2.5 rounded-lg border border-slate-200 bg-slate-50 text-slate-400 text-sm font-medium cursor-not-allowed"
            >
              <FileText className="w-4 h-4" />
              Export to Google Docs
              <span className="text-[10px] font-semibold bg-slate-100 text-slate-400 rounded-full px-1.5 py-0.5 uppercase tracking-wide ml-1">
                Coming Soon
              </span>
            </button>

          </div>

          <div className="rounded-lg border border-slate-200 bg-slate-50 px-4 py-4">
            <p className="text-xs font-semibold text-slate-600 mb-2">
              This brief is formatted for:
            </p>
            <ul className="space-y-1">
              {[
                "Entity-rich content that AI tools can parse and cite",
                "FAQ formatting optimised for AI-generated answer snippets",
                "Conversational query targeting for ChatGPT & Perplexity",
                "Consistent NAP and service entity signals",
                "Writer handoff — no raw HTML tags",
              ].map((item) => (
                <li key={item} className="flex items-center gap-2 text-xs text-slate-600">
                  <Check className="w-3 h-3 text-green-500 shrink-0" />
                  {item}
                </li>
              ))}
            </ul>
          </div>

        </div>
      </div>

      {/* Inline Schema Markup — LLMO flavour. Same component as the
          SEO brief but with briefType="llmo" which flips the server-
          side prompt to a citation-optimised system prompt (prefers
          Article / MedicalWebPage with SpeakableSpecification, full
          author + datePublished + dateModified metadata). Gated on
          briefId || effectiveKeyword so the section only shows
          once there's enough context to scaffold from. */}
      {(() => {
        const effectiveKeyword = (kwData?.primary?.keyword || service || "").trim();
        if (!selectedBrand?.id || (!briefId && !effectiveKeyword)) return null;
        return (
          <BriefSchemaSection
            brandId={selectedBrand?.id}
            briefType="llmo"
            title={service || effectiveKeyword || undefined}
            description={kwData?.primary?.keyword ? `LLMO-optimised content targeting "${kwData.primary.keyword}" for ${selectedBrand?.name || selectedBrand?.domain || ""}` : undefined}
            keyword={effectiveKeyword || undefined}
            secondaryKeywords={kwData?.secondary?.slice(0, 5).map((k) => k.keyword)}
            mode={mode}
            contentSignal={[service, city, effectiveKeyword].filter(Boolean).join(" ")}
          />
        );
      })()}

    </div>
  );
}
