/**
 * Per-post banner copy — dynamic headline, subhead, features, and CTA
 * derived from the current caption/story. Brand contact + logo stay fixed elsewhere.
 */

import type { ImageBrief } from "@/lib/generation/image-brief";
import type { FeatureIconKind } from "@/lib/generation/brand-visual-style";
import type { StoryContextSections } from "@/lib/generation/social-image";

export interface PostBannerFeature {
  label: string;
  detail: string;
  icon: FeatureIconKind;
}

export interface PostBannerContent {
  headline: string;
  subheadline: string;
  features: PostBannerFeature[];
  ctaSubline: string;
  visualHook: string;
}

const ICON_CYCLE: FeatureIconKind[] = [
  "service",
  "solution",
  "impact",
  "benefit",
  "challenge",
];

/** Beat-specific headline frames — prevents every post sharing one product slogan. */
const BEAT_HEADLINE_FRAMES = [
  (core: string) => core,
  (core: string) => `WHEN ${core.replace(/^WHEN\s+/i, "")}`,
  (core: string) => `${core.replace(/\.$/, "")} — WITHOUT THE NOISE`,
  (core: string) => `PROOF: ${core.replace(/^PROOF:\s*/i, "")}`,
  (core: string) => `NEXT: ${core.replace(/^NEXT:\s*/i, "")}`,
] as const;

function firstSentence(text: string, max = 100): string {
  const t = text.trim().replace(/\s+/g, " ");
  if (!t) return "";
  const m = t.match(/^[^.!?]+[.!?]?/);
  const s = (m?.[0] || t).trim();
  if (s.length <= max) return s.replace(/[.,;:]+$/, "") + (s.endsWith(".") ? "" : ".");
  const cut = s.slice(0, max);
  const sp = cut.lastIndexOf(" ");
  return (sp > 40 ? cut.slice(0, sp) : cut).replace(/[.,;:]+$/, "") + ".";
}

function labelFromPhrase(phrase: string, max = 28): string {
  const words = phrase
    .replace(/[^\w\s-]/g, " ")
    .split(/\s+/)
    .filter((w) => w.length > 2 && !/^(the|and|for|with|that|this|from|your|when|into)$/i.test(w))
    .slice(0, 4);
  if (!words.length) return "KEY CAPABILITY";
  return words.join(" ").toUpperCase().slice(0, max);
}

function hookFromCaption(caption: string): string | null {
  const bold = caption.match(/\*\*([^*]+)\*\*/);
  if (bold?.[1]?.trim()) return bold[1].trim().slice(0, 90);
  const line = caption.split("\n").find((l) => l.trim().length > 20 && !l.startsWith("#"));
  return line?.trim().slice(0, 90) ?? null;
}

/** Turn story problem/impact into a unique uppercase headline (not the product slogan). */
function headlineFromStoryBeat(input: {
  story?: StoryContextSections;
  caption: string;
  sequenceTitle?: string;
  sequenceIndex: number;
  layoutSeed: number;
}): string | null {
  const beat = Math.max(0, (input.sequenceIndex || 1) - 1) % 5;
  const problem = input.story?.problem?.trim() || "";
  const impact = input.story?.impact?.trim() || "";
  const theme = input.story?.keyTheme?.split("·").pop()?.trim() || "";
  const title = input.sequenceTitle?.replace(/^Post \d+ — /i, "").trim() || "";

  const candidates: string[] = [];
  if (problem) {
    // First clause of problem → headline core
    const clause = problem.split(/[.—:]/)[0]?.trim() || problem;
    const words = clause.split(/\s+/).filter(Boolean).slice(0, 10).join(" ");
    if (words.length >= 20) candidates.push(words);
  }
  if (impact) {
    const clause = impact.split(/[.—:]/)[0]?.trim() || impact;
    const words = clause.split(/\s+/).filter(Boolean).slice(0, 10).join(" ");
    if (words.length >= 18) candidates.push(words);
  }
  if (theme.length >= 8) candidates.push(theme);
  if (title.length >= 8 && !/^post\s*\d/i.test(title)) candidates.push(title);

  const captionHook = hookFromCaption(input.caption);
  if (captionHook && captionHook.length >= 18) candidates.push(captionHook);

  if (!candidates.length) return null;

  const pick = candidates[(beat + input.layoutSeed) % candidates.length]!;
  const frame = BEAT_HEADLINE_FRAMES[beat] ?? BEAT_HEADLINE_FRAMES[0]!;
  return frame(pick).replace(/\s+/g, " ").trim().slice(0, 90);
}

/** Build feature bullets unique to this post's story beat. */
function featuresFromStory(input: {
  story?: StoryContextSections;
  caption: string;
  sequenceIndex: number;
  layoutSeed: number;
  fallbackFeatures: PostBannerFeature[];
}): PostBannerFeature[] {
  const out: PostBannerFeature[] = [];
  const { story, caption, sequenceIndex, layoutSeed } = input;

  const slots: Array<{ label: string; detail: string }> = [];
  if (story?.problem?.trim()) {
    slots.push({
      label: labelFromPhrase(story.problem),
      detail: firstSentence(story.problem, 72),
    });
  }
  if (story?.impact?.trim()) {
    slots.push({
      label: labelFromPhrase(story.impact),
      detail: firstSentence(story.impact, 72),
    });
  }
  if (story?.brandResponse?.trim()) {
    slots.push({
      label: labelFromPhrase(story.brandResponse),
      detail: firstSentence(story.brandResponse, 72),
    });
  }
  if (story?.keyTheme?.trim()) {
    slots.push({
      label: labelFromPhrase(story.keyTheme),
      detail: firstSentence(story.keyTheme, 72),
    });
  }

  if (slots.length < 3) {
    const sentences = caption
      .replace(/#\w+/g, "")
      .split(/(?<=[.!?])\s+/)
      .filter((s) => s.length > 35 && s.length < 140);
    const pick = sentences[(sequenceIndex + layoutSeed) % Math.max(sentences.length, 1)];
    if (pick) {
      slots.push({ label: labelFromPhrase(pick), detail: firstSentence(pick, 72) });
    }
  }

  const rotated = [...input.fallbackFeatures];
  if (rotated.length > 1) {
    const rot = (sequenceIndex + layoutSeed) % rotated.length;
    rotated.push(...rotated.splice(0, rot));
  }

  for (let i = 0; i < 4; i++) {
    const fromStory = slots[i];
    const fromBrand = rotated[i];
    if (fromStory && fromStory.label.length > 3) {
      out.push({
        label: fromStory.label.slice(0, 28),
        detail: fromStory.detail.slice(0, 80),
        icon: ICON_CYCLE[(sequenceIndex + i + layoutSeed) % ICON_CYCLE.length]!,
      });
    } else if (fromBrand) {
      out.push(fromBrand);
    }
  }

  return out.slice(0, 4);
}

/**
 * Dynamic banner copy for ONE post — changes every sequence beat / regenerate.
 * Never reuse a single product slogan for every post in the campaign.
 */
export function buildPostBannerContent(input: {
  caption: string;
  storySections?: StoryContextSections;
  imageBrief?: ImageBrief | null;
  sequenceTitle?: string;
  sequenceIndex: number;
  layoutSeed: number;
  productHeadline?: string;
  productSubheadline?: string;
  solutionCategory?: string;
  brandFeatures?: Array<{ label: string; detail: string; icon: FeatureIconKind }>;
}): PostBannerContent {
  const brief = input.imageBrief;
  const story = input.storySections;
  const productDefault = (input.productHeadline || "").trim().toUpperCase();
  const isAdmissions = input.solutionCategory === "education_admissions";

  const admissionsHeadlines = [
    "EVERY ADMISSION BEGINS WITH ONE SEARCH",
    "PARENT TRUST STARTS WITH A CLEAR NEXT STEP",
    "TURN EVERY INQUIRY INTO A GUIDED STUDENT JOURNEY",
    "MAKE EVERY ADMISSION STAGE VISIBLE",
    "BUILD TRUST. SIMPLIFY ADMISSIONS. GUIDE EVERY STUDENT",
  ] as const;

  // Prefer AI image-brief headline only if it is NOT a copy of the static product slogan.
  const briefHeadline = brief?.headline?.trim() || "";
  const briefIsUnique =
    Boolean(briefHeadline) &&
    (!productDefault ||
      (briefHeadline.toUpperCase() !== productDefault &&
        !briefHeadline.toUpperCase().includes("CRITICAL DOCUMENTS MOVE FASTER")));

  const storyHeadline = headlineFromStoryBeat({
    story,
    caption: input.caption,
    sequenceTitle: input.sequenceTitle,
    sequenceIndex: input.sequenceIndex,
    layoutSeed: input.layoutSeed,
  });

  const captionHook = hookFromCaption(input.caption);

  const headline =
    (isAdmissions
      ? admissionsHeadlines[
          Math.max(0, (input.sequenceIndex || 1) - 1) % admissionsHeadlines.length
        ]
      : "") ||
    (briefIsUnique ? briefHeadline : "") ||
    storyHeadline ||
    captionHook ||
    (story?.keyTheme ? labelFromPhrase(story.keyTheme, 72) : "") ||
    input.sequenceTitle?.replace(/^Post \d+ — /, "").trim() ||
    // Product slogan last — and only for beat 1; later beats get a framed variant
    (input.sequenceIndex <= 1
      ? productDefault || "MOVE FASTER WITH SMARTER COMMUNICATION"
      : `WHEN ${productDefault.replace(/^WHEN\s+/i, "") || "COMMUNICATION GETS SIMPLER"}`);

  let subheadline =
    brief?.subheadline?.trim() ||
    firstSentence(story?.impact || "", 120) ||
    firstSentence(story?.problem || "", 120) ||
    input.productSubheadline?.trim() ||
    firstSentence(input.caption.replace(/#\w+/g, ""), 120);

  if (subheadline.length > 120) {
    const cut = subheadline.slice(0, 120);
    const sp = cut.lastIndexOf(" ");
    subheadline = (sp > 70 ? cut.slice(0, sp) : cut).replace(/[.,;:]+$/, "") + ".";
  }

  const admissionsFeatures: PostBannerFeature[] = [
    { label: "CAPTURE EVERY INQUIRY", detail: "Connect search, messaging, email, and web", icon: "service" },
    { label: "FASTER COUNSELLING", detail: "Respond while student interest is active", icon: "solution" },
    { label: "DOCUMENT TRACKING", detail: "Make every admission stage transparent", icon: "benefit" },
    { label: "STUDENT CONVERSION", detail: "Guide genuine inquiries toward enrolment", icon: "impact" },
  ];

  const fallbackFeatures: PostBannerFeature[] = isAdmissions
    ? admissionsFeatures
    : (input.brandFeatures || []).map((f, i) => ({
        label: f.label.toUpperCase().slice(0, 28),
        detail: f.detail.slice(0, 80),
        icon: f.icon || ICON_CYCLE[i % ICON_CYCLE.length]!,
      }));

  const features = isAdmissions
    ? admissionsFeatures
    : featuresFromStory({
        story,
        caption: input.caption,
        sequenceIndex: input.sequenceIndex,
        layoutSeed: input.layoutSeed,
        fallbackFeatures,
      });

  const ctaSubline =
    (isAdmissions ? "Build trust. Simplify admissions. Guide every student." : "") ||
    firstSentence(story?.brandResponse || "", 60) ||
    brief?.keyStat?.trim() ||
    "See how teams simplify high-stakes communication.";

  const visualHook =
    brief?.visualConcept?.trim() ||
    story?.brandResponse?.slice(0, 160) ||
    story?.impact?.slice(0, 160) ||
    subheadline;

  return {
    headline: headline.toUpperCase().slice(0, 90),
    subheadline,
    features,
    ctaSubline,
    visualHook,
  };
}
