"use client";

import { useEffect, useRef, useState } from "react";
import type { MenuBoard } from "@/components/business/menu-boards/types";
import { useMenuBoardText } from "@/components/business/menu-boards/menuBoardI18n";
import { menuBoardSettingsWithDefaults } from "@/components/business/menu-boards/menuBoardDefaults";

type Props = {
  board: MenuBoard;
  large?: boolean;
  fixedRatio?: boolean;
  showFormatBadge?: boolean;
};

export default function MenuBoardPreviewSurface({ board, large = false, fixedRatio = false, showFormatBadge = true }: Props) {
  const t = useMenuBoardText();
  const viewportRef = useRef<HTMLDivElement>(null);
  const [canvasScale, setCanvasScale] = useState(1);
  const settings = menuBoardSettingsWithDefaults(board.settings);
  const sections = board.sections ?? [];
  // A board is the source of truth for its display. Never crop sections or items in the preview.
  const visibleSections = sections.filter((section) => section.isVisible !== false);
  const hasContent = visibleSections.length > 0;
  const font = settings.font!;
  const fontSizes = settings.fontSizes!;
  const fontFamily = font.preset === "editorial" ? "Georgia, 'Times New Roman', serif" : font.preset === "rounded" ? "ui-rounded, 'Arial Rounded MT Bold', system-ui, sans-serif" : font.preset === "mono" ? "ui-monospace, SFMono-Regular, Menlo, monospace" : font.preset === "custom" && font.url ? "MenuBoardEditorCustom, system-ui, sans-serif" : "system-ui, sans-serif";
  const aspectRatio = board.orientation === "LANDSCAPE" ? "16 / 9" : "9 / 16";
  const templateStyle = getTemplateStyle(settings.template, settings.theme);
  const totalItems = visibleSections.reduce((count, section) => count + section.items.length, 0);
  const columnCount = !large
    ? 1
    : board.orientation === "LANDSCAPE"
      ? visibleSections.length > 6 ? 4 : visibleSections.length > 2 ? 3 : 2
      : visibleSections.length > 10 ? 3 : visibleSections.length > 4 ? 2 : 1;
  const rowCount = Math.max(1, Math.ceil(visibleSections.length / columnCount));
  const density = large
    ? Math.max(0.52, Math.min(settings.contentDensity === "compact" ? 0.84 : 1, (settings.contentDensity === "compact" ? 0.84 : 1) - Math.max(0, rowCount - 2) * 0.12 - Math.max(0, totalItems / Math.max(visibleSections.length, 1) - 4) * 0.045))
    : 1;
  const compact = (size: number) => Math.max(9, Math.round(size * density));
  const fillContentArea = large && visibleSections.length >= 5;
  const sectionLayout = large
    ? `mt-8 grid w-full ${fillContentArea ? "min-h-0 flex-1 auto-rows-fr" : ""}`
    : "mt-6 space-y-5";
  const surface = settings.background ? undefined : settings.surfaceColor;
  const textColor = settings.textColor;
  const mutedStyle = settings.mutedColor ? { color: settings.mutedColor } : undefined;
  const headerAlignment = settings.headerAlignment ?? "center";
  const logoPosition = settings.logoPosition ?? "center";
  const headerClass = headerAlignment === "left" ? "text-left" : headerAlignment === "right" ? "text-right" : "text-center";
  const logoClass = logoPosition === "left" ? "mr-auto" : logoPosition === "right" ? "ml-auto" : "mx-auto";
  const sectionClass = settings.contentStyle === "cards"
    ? "rounded-lg p-3 shadow-sm"
    : settings.contentStyle === "minimal" ? "" : templateStyle.sectionClass;
  const dividerClass = settings.contentStyle === "minimal" ? "divide-transparent" : templateStyle.dividerClass;
  // This is a design canvas, not a device resolution. It keeps typography readable
  // while allowing the same board composition to scale precisely in every preview.
  const canvasWidth = board.orientation === "LANDSCAPE" ? 1280 : 720;
  const canvasHeight = board.orientation === "LANDSCAPE" ? 720 : 1280;

  useEffect(() => {
    if (!fixedRatio || !viewportRef.current) return;
    const viewport = viewportRef.current;
    const measure = () => {
      const nextScale = viewport.getBoundingClientRect().width / canvasWidth;
      setCanvasScale((current) => Math.abs(current - nextScale) < 0.001 ? current : nextScale);
    };
    measure();
    const observer = new ResizeObserver(measure);
    observer.observe(viewport);
    return () => observer.disconnect();
  }, [canvasWidth, fixedRatio]);

  const boardSurface = (
    <div
      className={`relative overflow-hidden rounded-xl border border-[var(--border)] ${fixedRatio ? "h-full w-full" : ""} ${templateStyle.textClass}`}
      style={{ ...templateStyle.surface, ...(surface ? { background: surface } : {}), borderTop: fixedRatio ? undefined : `${large ? 7 : 5}px solid ${settings.accentColor}`, aspectRatio: fixedRatio ? aspectRatio : undefined, fontFamily, ...(textColor ? { color: textColor } : {}) }}
    >
      {font.preset === "custom" && font.url && <style>{`@font-face { font-family: MenuBoardEditorCustom; src: url('${font.url}'); font-display: swap; }`}</style>}
      {fixedRatio && showFormatBadge && (
        <span className="absolute right-4 top-4 z-10 rounded-md px-2.5 py-1 text-xs font-semibold text-[var(--accent-fg)]" style={{ backgroundColor: settings.accentColor }}>
          {board.orientation === "LANDSCAPE" ? t("landscapeRatio") : t("portraitRatio")}
        </span>
      )}
      <div className={`relative overflow-hidden ${fixedRatio ? "h-full" : large ? "min-h-[560px]" : "min-h-[420px]"} ${large ? "p-5 xl:p-6" : "p-5"} ${settings.ticker ? "pb-14" : ""}`}>
        {settings.background && (
          <div className="absolute inset-0">
            {settings.background.type === "video" ? (
              <video src={settings.background.url} muted autoPlay loop playsInline className={`h-full w-full ${settings.background.fit === "contain" ? "object-contain" : "object-cover"}`} />
            ) : (
              // Menu-board uploads are user-provided and served by the existing asset endpoint.
              // eslint-disable-next-line @next/next/no-img-element
              <img src={settings.background.url} alt="" className={`h-full w-full ${settings.background.fit === "contain" ? "object-contain" : "object-cover"}`} />
            )}
            <div className="absolute inset-0 bg-black" style={{ opacity: (settings.background.overlay ?? 0) / 100 }} />
          </div>
        )}
        <div className="relative flex h-full flex-col">
          <header className={`shrink-0 ${headerClass}`}>
            {settings.brandLogo && (
              // The brand logo belongs to the board and is uploaded through the Menu Board asset endpoint.
              // eslint-disable-next-line @next/next/no-img-element
              <img src={settings.brandLogo} alt="" className={`mb-2 h-10 max-w-[42%] object-contain ${logoClass}`} />
            )}
            {settings.displayTitle && <h3 className="font-semibold leading-tight" style={{ color: settings.displayTitleColor, fontSize: fontSizes.title }}>{settings.displayTitle}</h3>}
            {hasContent && board.location && <p className={`mt-1 uppercase tracking-wide ${templateStyle.mutedClass}`} style={{ ...mutedStyle, fontSize: fontSizes.location }}>{board.location.name}</p>}
          </header>
          <div
            className={hasContent ? sectionLayout : "hidden"}
            style={large ? {
              gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`,
              ...(fillContentArea ? { gridTemplateRows: `repeat(${rowCount}, minmax(0, 1fr))` } : {}),
              gap: `${Math.max(10, Math.round(18 * density))}px`,
            } : undefined}
          >
            {visibleSections.map((section, sectionIndex) => (
              <div key={`${section.id ?? "section"}-${sectionIndex}`} className={sectionClass} style={settings.sectionSurfaceColor && settings.contentStyle !== "minimal" ? { backgroundColor: settings.sectionSurfaceColor } : undefined}>
                <h4 className="font-semibold leading-tight" style={{ color: settings.sectionTextColor ?? settings.accentColor, fontSize: compact(fontSizes.section) }}>{section.title}</h4>
                <div className={`divide-y ${dividerClass}`} style={{ marginTop: `${Math.max(4, Math.round(8 * density))}px` }}>
                  {section.items.filter((item) => settings.showUnavailable || item.isAvailable).map((item, index) => (
                    <div key={`${item.id ?? `${sectionIndex}-${item.name}`}-${index}`} className={`flex justify-between gap-3 ${item.isAvailable ? "" : "opacity-45"}`} style={{ paddingBlock: `${Math.max(2, Math.round(6 * density))}px` }}>
                      {item.imageUrl && (
                        // Product images are user-provided Menu Board assets.
                        // eslint-disable-next-line @next/next/no-img-element
                        <img src={item.imageUrl} alt="" className="h-9 w-9 shrink-0 rounded-md object-cover" />
                      )}
                      <span className="min-w-0">
                        <span className="block break-words" style={{ fontSize: compact(fontSizes.item) }}>{item.name}</span>
                        {settings.showDescriptions && item.description && <span className={`mt-0.5 block break-words ${templateStyle.mutedClass}`} style={{ ...mutedStyle, fontSize: compact(fontSizes.description) }}>{item.description}</span>}
                      </span>
                      <span className="shrink-0 font-semibold" style={{ color: settings.accentColor, fontSize: compact(fontSizes.price) }}>{item.price ? `$${item.price}` : ""}</span>
                    </div>
                  ))}
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
      {settings.ticker && <div className="absolute inset-x-0 bottom-0 z-20 px-5 py-2 text-center font-medium" style={{ backgroundColor: settings.accentColor, color: settings.tickerTextColor ?? "#0f172a", fontSize: fontSizes.ticker }}>{settings.ticker}</div>}
    </div>
  );

  if (!fixedRatio) return boardSurface;

  return (
    <div ref={viewportRef} className="relative h-full w-full overflow-hidden rounded-xl">
      <div
        className="absolute left-0 top-0 origin-top-left"
        style={{ width: canvasWidth, height: canvasHeight, transform: `scale(${canvasScale})` }}
      >
        {boardSurface}
      </div>
    </div>
  );
}

function getTemplateStyle(template?: string, theme?: string): {
  textClass: string;
  mutedClass: string;
  dividerClass: string;
  sectionClass: string;
  surface: React.CSSProperties;
} {
  if (template === "Signature quick serve") {
    return {
      textClass: "text-white",
      mutedClass: "text-white/65",
      dividerClass: "divide-white/15",
      sectionClass: "rounded-lg bg-black/18 p-3",
      surface: { background: "linear-gradient(135deg, #130807 0%, #2a0b08 45%, #0b0b0b 100%)" },
    };
  }
  if (template === "Golden combo board") {
    return {
      textClass: "text-slate-950",
      mutedClass: "text-slate-700",
      dividerClass: "divide-slate-950/15",
      sectionClass: "rounded-lg bg-white/65 p-3 shadow-sm",
      surface: { background: "linear-gradient(135deg, #fff7d6 0%, #fff 48%, #f7d25c 100%)" },
    };
  }
  if (template === "Coffee house calm") {
    return {
      textClass: "text-stone-50",
      mutedClass: "text-stone-300",
      dividerClass: "divide-stone-100/15",
      sectionClass: "rounded-lg bg-emerald-950/30 p-3",
      surface: { background: "linear-gradient(135deg, #17251f 0%, #244035 54%, #111827 100%)" },
    };
  }
  if (template === "Taproom chalk") {
    return {
      textClass: "text-zinc-100",
      mutedClass: "text-zinc-400",
      dividerClass: "divide-zinc-100/15",
      sectionClass: "rounded-lg border border-white/10 bg-black/20 p-3",
      surface: {
        background:
          "radial-gradient(circle at 18% 24%, rgba(255,255,255,0.07), transparent 24%), repeating-linear-gradient(0deg, #18181b 0, #18181b 10px, #1f1f22 11px)",
      },
    };
  }
  if (template === "Modern black menu") {
    return {
      textClass: "text-slate-50",
      mutedClass: "text-slate-400",
      dividerClass: "divide-slate-100/15",
      sectionClass: "rounded-lg bg-slate-900/60 p-3",
      surface: { background: "linear-gradient(135deg, #020617 0%, #0f172a 58%, #111827 100%)" },
    };
  }
  const light = theme === "light";
  return {
    textClass: light ? "bg-white text-slate-950" : "bg-zinc-950 text-white",
    mutedClass: light ? "text-slate-600" : "text-white/60",
    dividerClass: light ? "divide-slate-950/15" : "divide-white/15",
    sectionClass: "",
    surface: {},
  };
}
