import React, { useEffect, useMemo, useRef, useState } from "react";
import PptxGenJS from "pptxgenjs";
import jsPDF from "jspdf";
import html2canvas from "html2canvas";
import { useBrandKit } from "../../../utils/brand";
import { fileToDataUrl } from "../../../utils/file";

// ----- Types -----
type BgMode = "solid" | "image" | "stock";
type LogoPlacement = "none" | "top-left" | "top-right" | "bottom-left" | "bottom-right";
type ThemeKey = "centered" | "left" | "band" | "photoWash";

type StockItem = { id: string; thumb: string; full: string; credit?: string; };

// ----- Component -----
export default function DocumentCovers() {
  const brand = useBrandKit();

  // Core state
  const [title, setTitle] = useState("Your Presentation Title");
  const [subtitle, setSubtitle] = useState("Optional subtitle or tagline goes here");
  const [theme, setTheme] = useState<ThemeKey>("centered");

  // Background
  const [bgMode, setBgMode] = useState<BgMode>("solid");
  const [bgColor, setBgColor] = useState<string>(brand.colors.primary || "#05445e");
  const [washColor, setWashColor] = useState<string>(brand.colors.accent || "#f99f1b");
  const [washOpacity, setWashOpacity] = useState<number>(0.35);
  const [bgImageDataUrl, setBgImageDataUrl] = useState<string | null>(null);

  // Stock
  const [stockQuery, setStockQuery] = useState("abstract gradient");
  const [stockResults, setStockResults] = useState<StockItem[]>([]);
  const [stockLoading, setStockLoading] = useState(false);

  // Typography / Colors
  const [titleColor, setTitleColor] = useState<string>("#ffffff");
  const [subtitleColor, setSubtitleColor] = useState<string>("#d4f1f4");

  // Logo
  const [useLogo, setUseLogo] = useState<boolean>(!!brand.logo?.dataUrl);
  const [logoPlacement, setLogoPlacement] = useState<LogoPlacement>("top-right");
  const [logoScale, setLogoScale] = useState<number>(1);

  // Slide ratio & export options
  const [slideRatio, setSlideRatio] = useState<"16x9" | "4x3">("16x9");
  const [exportPdf, setExportPdf] = useState<boolean>(true);

  // Preview ref for PDF rasterization
  const previewRef = useRef<HTMLDivElement>(null);

  // Slide size (inches) for PPTX placement math
  const slideW = slideRatio === "16x9" ? 13.33 : 10;
  const slideH = 7.5;

  useEffect(() => {
    // optional: pre-search stock once
    // void searchStock();
  }, []);

  async function onPickBackgroundImage(e: React.ChangeEvent<HTMLInputElement>) {
    const f = e.target.files?.[0];
    if (!f) return;
    const data = await fileToDataUrl(f);
    setBgImageDataUrl(data);
    setBgMode("image");
  }

  async function searchStock() {
    setStockLoading(true);
    try {
      const r = await fetch(`/api/stock/photos?query=${encodeURIComponent(stockQuery)}&limit=12`);
      const j = await r.json();
      setStockResults(j.results || []);
    } catch (e) {
      setStockResults([]);
    } finally {
      setStockLoading(false);
    }
  }

  function applyBackgroundPptx(slide: PptxGenJS.Slide) {
    if (theme === "photoWash" || bgMode === "image" || bgMode === "stock") {
      const dataUrl = bgMode === "image" ? bgImageDataUrl : bgImageDataUrl; // stock also sets bgImageDataUrl
      if (dataUrl) {
        slide.background = { data: dataUrl };
      } else {
        slide.background = { color: bgColor };
      }
    } else {
      slide.background = { color: bgColor };
    }

    // Color wash overlay (for photo wash or band)
    if (theme === "photoWash") {
      slide.addShape(slide.parent.ShapeType.rect, {
        x: 0,
        y: 0,
        w: slideW,
        h: slideH,
        fill: { color: hexToPptx(washColor), transparency: 100 - Math.round(washOpacity * 100) },
        line: { color: "000000", transparency: 100 }
      });
    }

    if (theme === "band") {
      const bandH = slideH * 0.38;
      slide.addShape(slide.parent.ShapeType.rect, {
        x: 0,
        y: (slideH - bandH) / 2,
        w: slideW,
        h: bandH,
        fill: { color: hexToPptx(brand.colors.accent || "#f99f1b"), transparency: 0 },
        line: { color: "000000", transparency: 100 }
      });
    }
  }

  function addLogoPptx(slide: PptxGenJS.Slide) {
    if (!(useLogo && brand.logo?.dataUrl) || logoPlacement === "none") return;
    const base = 1.6;
    const w = base * logoScale;
    const h = base * logoScale;
    const m = 0.35;
    let x = m, y = m;
    switch (logoPlacement) {
      case "top-left": x = m; y = m; break;
      case "top-right": x = slideW - w - m; y = m; break;
      case "bottom-left": x = m; y = slideH - h - m; break;
      case "bottom-right": x = slideW - w - m; y = slideH - h - m; break;
    }
    slide.addImage({ data: brand.logo.dataUrl!, x, y, w, h });
  }

  function addThemeContentPptx(slide: PptxGenJS.Slide) {
    const titleFont = brand.fonts?.heading || "Inter";
    const bodyFont  = brand.fonts?.body || "Inter";

    if (theme === "centered" || theme === "photoWash") {
      slide.addText(title, {
        x: 0.8, y: slideH * 0.32, w: slideW - 1.6, h: 1.6,
        align: "center", fontFace: titleFont, fontSize: 42, bold: true, color: hexToPptx(titleColor)
      });
      if (subtitle.trim()) {
        slide.addText(subtitle, {
          x: 1.2, y: slideH * 0.48, w: slideW - 2.4, h: 1.1,
          align: "center", fontFace: bodyFont, fontSize: 20, color: hexToPptx(subtitleColor)
        });
      }
    }

    if (theme === "left") {
      // left aligned block
      slide.addText(title, {
        x: 1.0, y: slideH * 0.34, w: slideW * 0.55, h: 2.0,
        align: "left", fontFace: titleFont, fontSize: 44, bold: true, color: hexToPptx(titleColor)
      });
      if (subtitle.trim()) {
        slide.addText(subtitle, {
          x: 1.0, y: slideH * 0.52, w: slideW * 0.55, h: 1.2,
          align: "left", fontFace: bodyFont, fontSize: 20, color: hexToPptx(subtitleColor)
        });
      }
      // optional decorative bar
      slide.addShape(slide.parent.ShapeType.rect, {
        x: 0.8, y: slideH * 0.3, w: 0.12, h: slideH * 0.4,
        fill: { color: hexToPptx(brand.colors.accent || "#f99f1b") }, line: { color: "000000", transparency: 100 }
      });
    }

    if (theme === "band") {
      // centered text on color band
      slide.addText(title, {
        x: 0.8, y: slideH * 0.32, w: slideW - 1.6, h: 1.6,
        align: "center", fontFace: titleFont, fontSize: 42, bold: true, color: hexToPptx(titleColor)
      });
      if (subtitle.trim()) {
        slide.addText(subtitle, {
          x: 1.2, y: slideH * 0.48, w: slideW - 2.4, h: 1.1,
          align: "center", fontFace: bodyFont, fontSize: 20, color: hexToPptx(subtitleColor)
        });
      }
    }
  }

  function generatePptx(singleTheme?: ThemeKey) {
    const themes: ThemeKey[] = singleTheme ? [singleTheme] : [theme];
    const pptx = new PptxGenJS();
    pptx.layout = slideRatio === "16x9" ? "LAYOUT_16x9" : "LAYOUT_4x3";

    themes.forEach((t) => {
      const slide = pptx.addSlide();
      // adjust temp theme to render
      const prevTheme = theme;
      (theme as any) = t;

      applyBackgroundPptx(slide);
      addThemeContentPptx(slide);
      addLogoPptx(slide);

      (theme as any) = prevTheme; // restore
    });

    const brandName = brand.name || "Brand";
    const safeTitle = title.replace(/[\\/:*?"<>|]/g, "").slice(0, 80);
    const filename = `${brandName} - ${safeTitle || "Cover"}.pptx`;
    pptx.writeFile({ fileName: filename });
  }

  async function exportPdfFromPreview() {
    if (!previewRef.current) return;

    const el = previewRef.current;
    const canvas = await html2canvas(el, { backgroundColor: null, scale: 2 });
    const imgData = canvas.toDataURL("image/png");

    // Size for PDF: A4 landscape (or US Letter). We'll use A4 landscape here.
    const pdf = new jsPDF({ orientation: "landscape", unit: "pt", format: "a4" });
    const pageW = pdf.internal.pageSize.getWidth();
    const pageH = pdf.internal.pageSize.getHeight();

    // Fit image preserving aspect
    const imgW = pageW;
    const imgH = (canvas.height / canvas.width) * imgW;
    const y = (pageH - imgH) / 2;
    pdf.addImage(imgData, "PNG", 0, Math.max(0, y), imgW, imgH);

    const brandName = brand.name || "Brand";
    const safeTitle = title.replace(/[\\/:*?"<>|]/g, "").slice(0, 80);
    pdf.save(`${brandName} - ${safeTitle || "Cover"}.pdf`);
  }

  async function handleExport() {
    generatePptx();
    if (exportPdf) {
      await exportPdfFromPreview();
    }
  }

  // Batch export 4 themes
  async function handleBatchExport() {
    const batch: ThemeKey[] = ["left", "centered", "band", "photoWash"];
    const pptx = new PptxGenJS();
    pptx.layout = slideRatio === "16x9" ? "LAYOUT_16x9" : "LAYOUT_4x3";

    const prevTheme = theme;
    for (const t of batch) {
      (theme as any) = t;
      const slide = pptx.addSlide();
      applyBackgroundPptx(slide);
      addThemeContentPptx(slide);
      addLogoPptx(slide);
    }
    (theme as any) = prevTheme;

    const brandName = brand.name || "Brand";
    const safeTitle = title.replace(/[\\/:*?"<>|]/g, "").slice(0, 80);
    await pptx.writeFile({ fileName: `${brandName} - ${safeTitle || "Covers"} (Batch).pptx` });

    if (exportPdf && previewRef.current) {
      // Optional: also save a PDF per current preview (single). Batch PDF per theme would require
      // re-rendering each theme preview; we can wire that later if you want.
      await exportPdfFromPreview();
    }
  }

  // Preview CSS background
  const previewBg: React.CSSProperties = useMemo(() => {
    if (theme === "photoWash" || bgMode === "image" || bgMode === "stock") {
      return bgImageDataUrl
        ? { background: `center/cover no-repeat url(${bgImageDataUrl})` }
        : { background: bgColor };
    }
    return { background: bgColor };
  }, [bgMode, bgColor, bgImageDataUrl, theme]);

  return (
    <div className="p-6 space-y-6">
      <h1 className="text-2xl font-bold">Document Covers</h1>
      <p className="text-slate-300">Multiple themes with brand colors, fonts, logo. Export <b>PPTX</b> and optional <b>PDF</b>.</p>

      {/* Brand kit summary */}
      <div className="rounded-xl border border-white/10 bg-slate-900/60 p-4">
        <div className="text-sm text-slate-400">Brand Kit</div>
        <div className="mt-2 flex flex-wrap items-center gap-4">
          <div>
            <div className="text-xs text-slate-400">Brand</div>
            <div className="font-medium">{brand.name || "Untitled Brand"}</div>
          </div>
          <div>
            <div className="text-xs text-slate-400">Fonts</div>
            <div className="text-sm">
              <span className="font-semibold">Heading:</span> {brand.fonts?.heading || "Inter"} &nbsp;•&nbsp;
              <span className="font-semibold">Body:</span> {brand.fonts?.body || "Inter"}
            </div>
          </div>
          <div className="flex items-center gap-2">
            {Object.entries(brand.colors)
              .slice(0, 6)
              .map(([k, v]) => (
                <div key={k} className="text-center">
                  <div className="h-6 w-6 rounded" style={{ background: v }} />
                  <div className="text-[10px] text-slate-400 mt-1">{k}</div>
                </div>
              ))}
          </div>
        </div>
      </div>

      <div className="grid xl:grid-cols-2 gap-6">
        {/* Controls */}
        <div className="rounded-xl border border-white/10 bg-slate-900/60 p-5">
          <div className="grid gap-4">
            {/* Title / Subtitle */}
            <div>
              <label className="text-sm text-slate-300">Title</label>
              <input
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                className="mt-1 w-full rounded-lg bg-slate-950/60 border border-white/10 p-2 text-slate-100 focus:outline-none focus:ring-2 focus:ring-sky-500/40"
              />
            </div>
            <div>
              <label className="text-sm text-slate-300">Subtitle</label>
              <input
                value={subtitle}
                onChange={(e) => setSubtitle(e.target.value)}
                className="mt-1 w-full rounded-lg bg-slate-950/60 border border-white/10 p-2 text-slate-100 focus:outline-none focus:ring-2 focus:ring-sky-500/40"
              />
            </div>

            {/* Theme */}
            <div>
              <label className="text-sm text-slate-300">Theme</label>
              <div className="mt-2 flex flex-wrap gap-2">
                {(["centered", "left", "band", "photoWash"] as ThemeKey[]).map((t) => (
                  <button
                    key={t}
                    className={`px-3 py-1.5 rounded-lg border text-sm ${
                      theme === t ? "bg-white/10 border-white/20" : "border-white/10 hover:bg-white/5"
                    }`}
                    onClick={() => setTheme(t)}
                  >
                    {labelTheme(t)}
                  </button>
                ))}
              </div>
            </div>

            {/* Colors */}
            <div className="flex flex-wrap gap-6">
              <div>
                <label className="text-sm text-slate-300">Title Color</label>
                <input type="color" value={titleColor} onChange={(e) => setTitleColor(e.target.value)} className="block mt-1 h-9 w-12 bg-transparent" />
              </div>
              <div>
                <label className="text-sm text-slate-300">Subtitle Color</label>
                <input type="color" value={subtitleColor} onChange={(e) => setSubtitleColor(e.target.value)} className="block mt-1 h-9 w-12 bg-transparent" />
              </div>
            </div>

            {/* Background mode */}
            <div>
              <label className="text-sm text-slate-300">Background</label>
              <div className="mt-2 flex items-center gap-4">
                {(["solid", "image", "stock"] as BgMode[]).map((m) => (
                  <label key={m} className="inline-flex items-center gap-2">
                    <input type="radio" className="accent-sky-500" checked={bgMode === m} onChange={() => setBgMode(m)} />
                    {labelBg(m)}
                  </label>
                ))}
              </div>

              {bgMode === "solid" && (
                <div className="mt-2">
                  <input type="color" value={bgColor} onChange={(e) => setBgColor(e.target.value)} className="h-9 w-12 bg-transparent" />
                </div>
              )}

              {bgMode === "image" && (
                <div className="mt-2">
                  <input type="file" accept="image/*" onChange={onPickBackgroundImage}
                    className="block text-sm text-slate-300 file:mr-3 file:py-1.5 file:px-3 file:rounded-lg file:border-0 file:text-sm file:bg-slate-800 file:text-white hover:file:bg-slate-700" />
                  {!bgImageDataUrl && <p className="text-xs text-slate-400 mt-1">Choose a large image (1920×1080+) for best quality.</p>}
                </div>
              )}

              {bgMode === "stock" && (
                <div className="mt-2">
                  <div className="flex gap-2">
                    <input
                      value={stockQuery}
                      onChange={(e) => setStockQuery(e.target.value)}
                      className="flex-1 rounded-lg bg-slate-950/60 border border-white/10 p-2 text-slate-100 focus:outline-none focus:ring-2 focus:ring-sky-500/40"
                      placeholder="Search stock (e.g., abstract, office, city night)…"
                    />
                    <button onClick={searchStock} className="px-3 py-2 rounded-lg bg-sky-600 hover:bg-sky-700 text-white disabled:opacity-60" disabled={stockLoading}>
                      {stockLoading ? "Searching…" : "Search"}
                    </button>
                  </div>
                  <div className="mt-3 grid grid-cols-3 md:grid-cols-4 xl:grid-cols-5 gap-3">
                    {stockResults.map((it) => (
                      <button key={it.id}
                        className="group rounded-lg overflow-hidden border border-white/10 hover:border-sky-500/50"
                        onClick={() => {
                          setBgImageDataUrl(it.full);
                          setBgMode("stock");
                        }}>
                        <img src={it.thumb} alt="" className="w-full h-24 object-cover" />
                        {it.credit && <div className="text-[10px] p-1 text-slate-400 text-left">{it.credit}</div>}
                      </button>
                    ))}
                  </div>
                </div>
              )}
            </div>

            {/* Photo wash controls */}
            {theme === "photoWash" && (
              <div className="flex flex-wrap gap-6">
                <div>
                  <label className="text-sm text-slate-300">Wash Color</label>
                  <input type="color" value={washColor} onChange={(e) => setWashColor(e.target.value)} className="block mt-1 h-9 w-12 bg-transparent" />
                </div>
                <div className="flex-1">
                  <label className="text-sm text-slate-300">Wash Opacity ({washOpacity.toFixed(2)})</label>
                  <input type="range" min={0} max={0.9} step={0.05} value={washOpacity} onChange={(e) => setWashOpacity(parseFloat(e.target.value))} className="w-full" />
                </div>
              </div>
            )}

            {/* Logo */}
            <div className="rounded-lg border border-white/10 p-3">
              <label className="inline-flex items-center gap-2">
                <input type="checkbox" className="accent-sky-500" checked={useLogo} onChange={(e) => setUseLogo(e.target.checked)} />
                <span className="text-sm text-slate-300">Include brand logo</span>
              </label>
              <div className="mt-3 grid grid-cols-2 gap-3">
                <div>
                  <div className="text-xs text-slate-400 mb-1">Placement</div>
                  <div className="flex flex-wrap gap-2">
                    {(["none", "top-left", "top-right", "bottom-left", "bottom-right"] as LogoPlacement[]).map((p) => (
                      <button key={p}
                        className={`px-2.5 py-1.5 rounded border text-xs ${logoPlacement === p ? "bg-white/10 border-white/20" : "border-white/10 hover:bg-white/5"}`}
                        onClick={() => setLogoPlacement(p)}
                      >
                        {p.replace("-", " ")}
                      </button>
                    ))}
                  </div>
                </div>
                <div>
                  <div className="text-xs text-slate-400 mb-1">Size</div>
                  <input type="range" min={0.6} max={2} step={0.1} value={logoScale} onChange={(e) => setLogoScale(parseFloat(e.target.value))} className="w-full" />
                </div>
              </div>
              {!brand.logo?.dataUrl && <p className="text-xs text-amber-300 mt-2">No logo found in Brand Kit. Add one to enable this.</p>}
            </div>

            {/* Slide ratio & export */}
            <div className="flex flex-wrap gap-6 items-center">
              <div>
                <label className="text-sm text-slate-300">Slide Ratio</label>
                <div className="mt-1 flex gap-2">
                  <button className={`px-3 py-1.5 rounded-lg border ${slideRatio === "16x9" ? "bg-white/10 border-white/20" : "border-white/10 hover:bg-white/5"}`} onClick={() => setSlideRatio("16x9")}>16:9</button>
                  <button className={`px-3 py-1.5 rounded-lg border ${slideRatio === "4x3" ? "bg-white/10 border-white/20" : "border-white/10 hover:bg-white/5"}`} onClick={() => setSlideRatio("4x3")}>4:3</button>
                </div>
              </div>
              <label className="inline-flex items-center gap-2">
                <input type="checkbox" className="accent-sky-500" checked={exportPdf} onChange={(e) => setExportPdf(e.target.checked)} />
                <span className="text-sm text-slate-300">Also export PDF</span>
              </label>
            </div>

            {/* Actions */}
            <div className="pt-2 flex flex-wrap gap-3">
              <button onClick={handleExport} className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-sky-600 hover:bg-sky-700 text-white">
                Generate PPTX {exportPdf ? "+ PDF" : ""}
              </button>
              <button onClick={handleBatchExport} className="inline-flex items-center gap-2 px-4 py-2 rounded-lg bg-emerald-600 hover:bg-emerald-700 text-white">
                Batch Export (4 themes)
              </button>
            </div>
          </div>
        </div>

        {/* Live Preview */}
        <div className="rounded-xl border border-white/10 bg-slate-900/60 p-5">
          <div className="text-sm text-slate-300 mb-2">Preview</div>
          <div ref={previewRef}
            className={`relative w-full ${slideRatio === "16x9" ? "aspect-video" : "aspect-[4/3]"} overflow-hidden rounded-xl border border-white/10`}
            style={previewBg}
          >
            {/* photo wash overlay */}
            {theme === "photoWash" && (
              <div className="absolute inset-0" style={{ background: washColor, opacity: washOpacity }} />
            )}

            {/* band */}
            {theme === "band" && (
              <div className="absolute inset-y-0 left-0 right-0" style={{
                top: "31%",
                bottom: "31%",
                background: brand.colors.accent || "#f99f1b",
                opacity: 1
              }} />
            )}

            {/* Title/Sub by theme */}
            {(theme === "centered" || theme === "photoWash" || theme === "band") && (
              <>
                <div style={{
                  position: "absolute", left: "6%", right: "6%", top: "32%", textAlign: "center",
                  fontFamily: brand.fonts?.heading || "Inter", fontWeight: 800, fontSize: "2.4rem", color: titleColor,
                  textShadow: "0 2px 8px rgba(0,0,0,0.35)"
                }}>{title}</div>
                {subtitle.trim() && (
                  <div style={{
                    position: "absolute", left: "10%", right: "10%", top: "48%", textAlign: "center",
                    fontFamily: brand.fonts?.body || "Inter", fontWeight: 500, fontSize: "1.05rem", color: subtitleColor,
                    textShadow: "0 1px 6px rgba(0,0,0,0.3)"
                  }}>{subtitle}</div>
                )}
              </>
            )}

            {theme === "left" && (
              <>
                <div style={{
                  position: "absolute", left: "8%", top: "34%", width: "54%",
                  fontFamily: brand.fonts?.heading || "Inter", fontWeight: 800, fontSize: "2.6rem", color: titleColor,
                  lineHeight: 1.1, textShadow: "0 2px 8px rgba(0,0,0,0.35)"
                }}>{title}</div>
                {subtitle.trim() && (
                  <div style={{
                    position: "absolute", left: "8%", top: "52%", width: "54%",
                    fontFamily: brand.fonts?.body || "Inter", fontWeight: 500, fontSize: "1.05rem", color: subtitleColor,
                    textShadow: "0 1px 6px rgba(0,0,0,0.3)"
                  }}>{subtitle}</div>
                )}
                <div style={{ position: "absolute", left: "6%", top: "30%", width: 6, height: "40%", background: brand.colors.accent || "#f99f1b" }} />
              </>
            )}

            {/* Logo */}
            {useLogo && brand.logo?.dataUrl && logoPlacement !== "none" && (
              <img
                src={brand.logo.dataUrl}
                alt="logo"
                style={{
                  position: "absolute",
                  width: `${8 * logoScale}%`,
                  aspectRatio: "1 / 1",
                  ...(logoPlacement.includes("top") ? { top: "3%" } : { bottom: "3%" }),
                  ...(logoPlacement.includes("left") ? { left: "3%" } : { right: "3%" }),
                  opacity: 0.95,
                  filter: "drop-shadow(0 2px 6px rgba(0,0,0,0.35))",
                }}
              />
            )}
          </div>

          <p className="mt-3 text-xs text-slate-400">
            PDF is rendered from this preview (raster). PPTX is vector text/shapes using your Brand Kit fonts (see notes below).
          </p>
        </div>
      </div>
    </div>
  );
}

// ----- Helpers -----
function hexToPptx(hex: string): string {
  const clean = hex.replace("#", "");
  return clean.length === 6 ? clean.toUpperCase() : "FFFFFF";
}
function labelTheme(t: ThemeKey) {
  switch (t) {
    case "centered": return "Centered";
    case "left": return "Left-aligned";
    case "band": return "Color Band";
    case "photoWash": return "Photo + Color Wash";
  }
}
function labelBg(m: BgMode) {
  switch (m) {
    case "solid": return "Solid";
    case "image": return "Image Upload";
    case "stock": return "Stock Library";
  }
}
