import { applyMergeTags, type MergeVars } from "@/lib/blocks/merge";
import { toEmbedUrl } from "@/lib/security/url";
import type { BlockOf } from "@/lib/blocks/schema";
import { cn } from "@/lib/utils";
import { Heading, Section, SafeLink, buttonCls, buttonOnPrimaryCls } from "./section";
import { MediaImage } from "./media-image";
import { Markup } from "./markup";
import type { MediaInfo } from "./types";


export function HeroBlock({ block, media, first }: { block: BlockOf<"hero">; media: MediaInfo; first: boolean }) {
  const { props, style } = block;
  const hasImage = Boolean(props.imageId && media.has(props.imageId));
  return (
    <Section style={style} label={props.heading}>
      <div className={cn("grid items-center gap-8", hasImage && "md:grid-cols-2", props.align === "center" && !hasImage && "text-center")}>
        <div className={cn(props.align === "center" && !hasImage && "mx-auto max-w-3xl")}>
          <Heading level={first ? 1 : 2}>{props.heading}</Heading>
          {props.subheading && <p className="text-lg opacity-85">{props.subheading}</p>}
          {props.ctaLabel && props.ctaUrl && (
            <p className="mt-6">
              <SafeLink href={props.ctaUrl} className={style.background === "primary" || style.background === "dark" ? buttonOnPrimaryCls : buttonCls}>
                {props.ctaLabel}
              </SafeLink>
            </p>
          )}
        </div>
        {hasImage && <MediaImage id={props.imageId} media={media} priority={first} className="w-full rounded-xl object-cover" />}
      </div>
    </Section>
  );
}

/** Plain text: blank line = new paragraph. Rendered as text nodes only (never as HTML). */
function Paragraphs({ text }: { text: string }) {
  return (
    <>
      {text.split(/\n{2,}/).map((p, i) => (
        <p key={i} className="mb-4 whitespace-pre-line leading-relaxed">{p}</p>
      ))}
    </>
  );
}

export function RichTextBlock({ block, vars }: { block: BlockOf<"richText">; vars: MergeVars }) {
  const { props, style } = block;
  return (
    <Section style={style} label={applyMergeTags(props.heading, vars)}>
      <div className={cn(props.align === "center" && "mx-auto max-w-3xl text-center")}>
        <Heading>{applyMergeTags(props.heading, vars)}</Heading>
        <Markup text={applyMergeTags(props.body, vars)} />
      </div>
    </Section>
  );
}

export function TextImageBlock({ block, media }: { block: BlockOf<"textImage">; media: MediaInfo }) {
  const { props, style } = block;
  const hasImage = Boolean(props.imageId && media.has(props.imageId));
  return (
    <Section style={style} label={props.heading}>
      <div className={cn("grid items-center gap-8", hasImage && "md:grid-cols-2")}>
        <div className={cn(props.imagePosition === "left" && "md:order-2")}>
          <Heading>{props.heading}</Heading>
          <Paragraphs text={props.body} />
        </div>
        {hasImage && <MediaImage id={props.imageId} media={media} className={cn("w-full rounded-xl object-cover", props.imagePosition === "left" && "md:order-1")} />}
      </div>
    </Section>
  );
}

export function GalleryBlock({ block, media }: { block: BlockOf<"gallery">; media: MediaInfo }) {
  const { props, style } = block;
  const items = props.items.filter((i) => media.has(i.mediaId));
  if (items.length === 0) return null;
  return (
    <Section style={style} label={props.heading || "Gallery"}>
      <Heading>{props.heading}</Heading>
      <ul className="grid grid-cols-2 gap-4 md:grid-cols-3">
        {items.map((item, i) => (
          <li key={`${item.mediaId}-${i}`}>
            <figure>
              <MediaImage id={item.mediaId} media={media} className="aspect-[4/3] w-full rounded-lg object-cover" />
              {(item.caption || media.get(item.mediaId)?.caption) && <figcaption className="mt-2 text-sm opacity-75">{item.caption || media.get(item.mediaId)?.caption}</figcaption>}
            </figure>
          </li>
        ))}
      </ul>
    </Section>
  );
}

const COLS = { "2": "md:grid-cols-2", "3": "md:grid-cols-3", "4": "md:grid-cols-2 lg:grid-cols-4" } as const;

export function CardGridBlock({ block, media }: { block: BlockOf<"cardGrid">; media: MediaInfo }) {
  const { props, style } = block;
  return (
    <Section style={style} label={props.heading || "Cards"}>
      <Heading>{props.heading}</Heading>
      <ul className={cn("grid gap-6", COLS[props.columns])}>
        {props.cards.map((c, i) => (
          <li key={i} className="blk-card overflow-hidden">
            <MediaImage id={c.imageId} media={media} className="aspect-[16/9] w-full object-cover" />
            <div className="p-5">
              <h3 className="text-lg font-semibold">{c.linkUrl ? <SafeLink href={c.linkUrl} className="hover:underline">{c.title}</SafeLink> : c.title}</h3>
              {c.text && <p className="mt-2 text-sm opacity-80">{c.text}</p>}
            </div>
          </li>
        ))}
      </ul>
    </Section>
  );
}

export function StatsBlock({ block }: { block: BlockOf<"stats"> }) {
  const { props, style } = block;
  return (
    <Section style={style} label={props.heading || "Key figures"}>
      <Heading>{props.heading}</Heading>
      <dl className="grid grid-cols-2 gap-6 text-center md:grid-cols-4">
        {props.items.map((s, i) => (
          <div key={i}>
            <dd className="text-4xl font-bold">{s.value}</dd>
            <dt className="mt-1 text-sm opacity-80">{s.label}</dt>
          </div>
        ))}
      </dl>
    </Section>
  );
}

export function TestimonialsBlock({ block }: { block: BlockOf<"testimonials"> }) {
  const { props, style } = block;
  return (
    <Section style={style} label={props.heading || "Testimonials"}>
      <Heading>{props.heading}</Heading>
      <ul className="grid gap-6 md:grid-cols-2">
        {props.items.map((t, i) => (
          <li key={i}>
            <figure className="blk-card p-6">
              <blockquote className="leading-relaxed">“{t.quote}”</blockquote>
              <figcaption className="mt-4 text-sm font-medium">
                {t.author}
                {t.role && <span className="font-normal opacity-70"> — {t.role}</span>}
              </figcaption>
            </figure>
          </li>
        ))}
      </ul>
    </Section>
  );
}

export function FaqBlock({ block }: { block: BlockOf<"faq"> }) {
  const { props, style } = block;
  return (
    <Section style={style} label={props.heading || "FAQ"}>
      <Heading>{props.heading}</Heading>
      <div className="mx-auto max-w-3xl blk-card divide-y divide-border">
        {props.items.map((f, i) => (
          <details key={i} className="group p-4">
            <summary className="cursor-pointer list-none font-medium marker:hidden">{f.question}</summary>
            <p className="mt-2 whitespace-pre-line text-sm opacity-85">{f.answer}</p>
          </details>
        ))}
      </div>
    </Section>
  );
}

export function VideoBlock({ block }: { block: BlockOf<"video"> }) {
  const { props, style } = block;
  const src = props.url ? toEmbedUrl(props.url) : null;
  if (!src) return null;
  return (
    <Section style={style} label={props.heading || "Video"}>
      <Heading>{props.heading}</Heading>
      <div className="mx-auto aspect-video w-full max-w-4xl overflow-hidden rounded-xl">
        <iframe src={src} title={props.title || "Video"} loading="lazy" className="h-full w-full border-0" allow="fullscreen; picture-in-picture" referrerPolicy="strict-origin-when-cross-origin" sandbox="allow-scripts allow-same-origin allow-presentation allow-popups" />
      </div>
    </Section>
  );
}

export function CtaBlock({ block }: { block: BlockOf<"cta"> }) {
  const { props, style } = block;
  const onDark = style.background === "primary" || style.background === "dark";
  return (
    <Section style={style} label={props.heading}>
      <div className="mx-auto max-w-2xl text-center">
        <Heading>{props.heading}</Heading>
        {props.text && <p className="mb-6 opacity-85">{props.text}</p>}
        <SafeLink href={props.buttonUrl} className={onDark ? buttonOnPrimaryCls : buttonCls}>{props.buttonLabel}</SafeLink>
      </div>
    </Section>
  );
}
