/**
 * POST /api/content-briefs/generate
 *
 * Generate the content-output block for a content brief. Two modes:
 *
 *   type: "seo"  — keyword-optimised editorial. H1/H2 structure,
 *                   meta description, headings target the keyword,
 *                   FAQ block at the end. Aimed at Google ranking.
 *   type: "llmo" — AI-citation optimised. Question → direct answer →
 *                   explanation → insight cadence. Short punchy answers
 *                   first (AI engines quote the first sentence of each
 *                   section). Aimed at ChatGPT/Perplexity/Gemini.
 *
 * The two prompts are intentionally separate — SEO and LLMO content
 * have different shapes, different hooks, and different success
 * criteria. Merging them into one "generic content" prompt dilutes
 * both. The prompt selection happens in `buildPrompt()` below.
 *
 * Output: `{ content: "...markdown...", provider, model, type }`
 * The caller displays the markdown as the generated brief body; the
 * existing Copy button serialises it straight to the clipboard.
 */

import { NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { callLlm } from "@/lib/ai-avatar/llm-client";
import { logAiInteraction } from "@/lib/services/ai-interaction-log";
import { trackEvent } from "@/lib/services/platform-telemetry";

export const dynamic = "force-dynamic";
export const maxDuration = 60;

interface GenerateBody {
  brandId?: string;
  keyword?: string;
  type?: "seo" | "llmo";
  /** "professional" | "conversational" | "persuasive" — display strings
   *  from the brief UI tone selectors. We lowercase internally. */
  tone?: string;
  /** `true` = humanised (natural / conversational); `false` = structured. */
  humanization?: boolean;
  /** Optional — falls back to keyword when omitted. */
  topic?: string;
  /** Optional — brand name override so the page can pass the editable
   *  brand input rather than whatever sits on the Brand row. */
  brandName?: string;
  city?: string;
  service?: string;
  ctaOffer?: string;
  /** Optional — detected specialty ("cardiology / cardiovascular") so
   *  the prompt can reference the right vertical. */
  specialty?: string | null;
}

// ─── Prompt builders ────────────────────────────────────────────────────────

function buildSystemPrompt(args: {
  type: "seo" | "llmo";
  tone: string;
  humanized: boolean;
}): string {
  const { type, tone, humanized } = args;

  const sharedFooter = humanized
    ? [
        "Write in a natural, human voice — vary sentence length, use contractions, and avoid AI-sounding filler phrases.",
        "Never open with 'In today's fast-paced world', 'In the realm of', 'It's important to note', or similar clichés.",
        "Favour concrete specifics over vague generalities.",
      ].join(" ")
    : [
        "Keep the voice clean and structured — this copy will be edited before publishing.",
        "Prefer plain declarative sentences. Avoid empty intensifiers.",
      ].join(" ");

  if (type === "seo") {
    return [
      "You are an SEO content strategist writing a publication-ready draft.",
      `Tone: ${tone}.`,
      "Optimise for Google rich results. Return a single Markdown document.",
      "",
      "Required structure (use these exact Markdown headings and labels):",
      "  **Meta Title:** (≤60 chars, includes primary keyword near the start)",
      "  **Meta Description:** (140-160 chars, action-oriented, includes keyword)",
      "  # (single H1 with the primary keyword)",
      "  Opening paragraph (2-3 sentences, answers the search query directly)",
      "  ## (H2 for each major section — 3-5 sections)",
      "  Body paragraphs under each H2 (2-3 paragraphs, 120-180 words each)",
      "  ### (H3 sub-sections where useful)",
      "  ## Frequently Asked Questions",
      "    **Q:** ... (3-5 FAQs, answers 50-90 words each)",
      "    **A:** ...",
      "  ## Call to Action",
      "    One short paragraph ending with a clear CTA sentence.",
      "",
      "Weave the primary keyword and natural variations through H1, first H2, meta title, and first paragraph. Do NOT keyword-stuff.",
      sharedFooter,
    ].join("\n");
  }

  // LLMO
  return [
    "You are an LLMO (Large Language Model Optimisation) content strategist.",
    "The goal is for ChatGPT, Perplexity, Gemini, and Claude to cite this page when users ask questions about the topic.",
    `Tone: ${tone}.`,
    "Return a single Markdown document.",
    "",
    "Required structure — each major block follows the Question → Answer → Explanation → Insight cadence:",
    "  **Title:** (a clear factual title, NOT click-bait)",
    "  Opening paragraph (2 sentences, states what the page covers in plain language)",
    "",
    "  For EACH of 4-5 top questions users ask AI engines about this topic:",
    "    ## [The question, phrased exactly how a user would type it into ChatGPT]",
    "    **Answer:** (1-2 sentence direct answer — AI engines will quote this first line verbatim)",
    "    **Explanation:** (3-6 sentences with concrete, citable specifics — numbers, names, locations, dates)",
    "    **Insight:** (1-2 sentences on WHY this matters or what it signals; establishes authority)",
    "",
    "  ## Key Takeaways",
    "    Bullet list of 4-6 short, factual takeaways (each ≤ 20 words).",
    "",
    "  ## Sources & Authority Signals",
    "    2-4 sentences explaining the author's credentials and why this page is a trustworthy source.",
    "",
    "Do NOT include SEO meta tags, Q&A schema JSON-LD, or keyword-density exercises — that's a separate output.",
    "Phrase headings as full natural-language questions (not keyword fragments).",
    sharedFooter,
  ].join("\n");
}

function buildUserPrompt(args: {
  type: "seo" | "llmo";
  keyword: string;
  topic: string;
  brandName: string;
  domain: string;
  city: string | null;
  service: string | null;
  specialty: string | null;
  ctaOffer: string | null;
}): string {
  const { type, keyword, topic, brandName, domain, city, service, specialty, ctaOffer } = args;

  const facts = [
    `Primary keyword / question: "${keyword}"`,
    `Topic: ${topic}`,
    `Brand: ${brandName}${domain ? ` (${domain})` : ""}`,
    service ? `Service or specialty: ${service}` : null,
    specialty ? `Vertical context: ${specialty}` : null,
    city ? `Primary city: ${city}` : null,
    ctaOffer ? `Preferred CTA: ${ctaOffer}` : null,
  ].filter(Boolean).join("\n");

  if (type === "seo") {
    return [
      "Write the SEO content draft described above for the following context:",
      "",
      facts,
      "",
      "Output the finished Markdown document only — no preamble, no sign-off, no explanatory notes.",
    ].join("\n");
  }

  return [
    "Write the LLMO content draft described above for the following context:",
    "",
    facts,
    "",
    "Pick 4-5 of the most-asked AI-chatbot questions about this topic as your H2s. Phrase them exactly how a real user would type them into ChatGPT.",
    "Output the finished Markdown document only — no preamble, no sign-off, no explanatory notes.",
  ].join("\n");
}

// ─── Handler ────────────────────────────────────────────────────────────────

export async function POST(req: Request) {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  let body: GenerateBody;
  try { body = await req.json(); }
  catch { return NextResponse.json({ error: "Invalid JSON" }, { status: 400 }); }

  const brandId = body.brandId?.trim();
  const keyword = body.keyword?.trim();
  const type: "seo" | "llmo" = body.type === "llmo" ? "llmo" : "seo";

  if (!brandId) return NextResponse.json({ error: "brandId required" }, { status: 400 });
  if (!keyword || keyword.length < 2) {
    return NextResponse.json({ error: "keyword required (min 2 chars)" }, { status: 400 });
  }

  // Access check — same pattern every /api/content-briefs/* route uses.
  const brand = await prisma.brand.findUnique({
    where: { id: brandId },
    include: { organization: { include: { memberships: true } } },
  });
  if (!brand) return NextResponse.json({ error: "Brand not found" }, { status: 404 });
  if (!brand.organization.memberships.some((m) => m.userId === user.id)) {
    return NextResponse.json({ error: "Access denied" }, { status: 403 });
  }

  const tone = (body.tone || "professional").toLowerCase();
  const humanized = body.humanization === true;
  const topic = (body.topic?.trim() || keyword);

  const systemPrompt = buildSystemPrompt({ type, tone, humanized });
  const userPrompt = buildUserPrompt({
    type,
    keyword,
    topic,
    brandName: body.brandName?.trim() || brand.name,
    domain: brand.domain || "",
    city: body.city?.trim() || null,
    service: body.service?.trim() || null,
    specialty: body.specialty?.trim() || null,
    ctaOffer: body.ctaOffer?.trim() || null,
  });

  // Longer generations are expected — 4500 tokens comfortably covers the
  // SEO brief (~1500-2000 words) and the LLMO brief (4-5 Q&A blocks).
  // If this is ever tightened, trim the LLMO block count first.
  const result = await callLlm(
    [
      { role: "system", content: systemPrompt },
      { role: "user", content: userPrompt },
    ],
    () =>
      type === "seo"
        ? `# ${topic}\n\n_(Mock draft — add ANTHROPIC_API_KEY or OPENAI_API_KEY to enable real generation.)_\n\nThis is a placeholder SEO draft for **${keyword}**.`
        : `**Title:** ${topic}\n\n_(Mock draft — add ANTHROPIC_API_KEY or OPENAI_API_KEY to enable real generation.)_\n\n## What is ${keyword}?\n\n**Answer:** Placeholder answer.\n**Explanation:** Placeholder explanation.\n**Insight:** Placeholder insight.`,
    { maxTokens: 4500 },
  );

  // Admin observability: guardrail-scored AI audit log + platform
  // telemetry event so /admin/ai-monitor + engagement dashboards
  // populate automatically. Both writes are fire-and-forget.
  logAiInteraction({
    userId: user.id,
    brandId,
    feature: type === "llmo" ? "llmo_brief" : "content_brief",
    userPrompt,
    systemPrompt,
    aiResponse: result.reply,
    model: result.model,
    brandDomain: brand.domain,
  });
  trackEvent({
    userId: user.id,
    brandId,
    action: "content_brief_created",
    category: "content",
    metadata: { keyword, type, tone, humanized, provider: result.provider, model: result.model },
    request: req,
  });

  return NextResponse.json({
    content: result.reply,
    provider: result.provider,
    model: result.model,
    type,
    tone,
    humanized,
  });
}
