import { useState } from "react";
import { X, Sparkles, Wand2, Loader2, Check, ArrowRight } from "lucide-react";
import { useStore, type SceneSpec } from "../store";
import { MG_THEME_LIST, MG_ACCENTS, MG_TEMPLATES, type ThemeKey } from "../remotion/mg/templates";
import { MG_FONTS } from "../remotion/mg/catalog.mjs";
import { aiHeaders } from "../lib/aiKeys";

const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

// the cohesive subset of type systems worth surfacing here (caps-display + Arabic presets are omitted —
// they only read well with very short copy / RTL). "Auto" lets the AI director pick the best-fitting one.
const FONT_PICK_IDS = ["grotesk", "clean", "geometric", "modern", "tech", "editorial", "elegant", "magazine", "mono", "condensed"];
const FONT_PICKS = FONT_PICK_IDS.map((id) => MG_FONTS.find((f: { id: string }) => f.id === id)).filter(Boolean) as { id: string; label: string; blurb: string; preview: string }[];

// Guided, step-by-step generator: pick a look → AI writes on-topic scenes →
// they drop onto the timeline one at a time so you can watch the build.
export function GenerateScenesModal({ open, onClose }: { open: boolean; onClose: () => void }) {
  const projectName = useStore((s) => s.projectName);
  const words = useStore((s) => s.words);
  const sections = useStore((s) => s.sections);
  const addGeneratedScene = useStore((s) => s.addGeneratedScene);
  const selectMotion = useStore((s) => s.selectMotion);

  const [theme, setTheme] = useState<ThemeKey>("dark");
  const [accent, setAccent] = useState(MG_ACCENTS[0]);
  const [font, setFont] = useState(""); // "" = Auto (the AI picks one cohesive type system for the whole set)
  const [count, setCount] = useState(5);
  const [topic, setTopic] = useState("");
  const [phase, setPhase] = useState<"setup" | "running" | "done">("setup");
  const [log, setLog] = useState<{ label: string; template: string; state: "pending" | "active" | "done" }[]>([]);
  const [err, setErr] = useState("");
  const [skipped, setSkipped] = useState(0);

  if (!open) return null;

  async function run() {
    setErr("");
    setPhase("running");
    setLog([]);
    try {
      const res = await fetch("/api/generate-scenes", {
        method: "POST", headers: { "Content-Type": "application/json", ...aiHeaders() },
        body: JSON.stringify({
          topic: topic.trim() || projectName,
          count, font: font || undefined, // omit → AI picks one cohesive typeface; set → locks it
          transcript: words.slice(0, 400).map((w) => w.text).join(" "),
          sections: sections.map((s) => ({ title: s.title })),
        }),
      }).catch(() => { throw new Error("couldn't reach the generator — is the dev server running? try again"); });
      const d = await res.json();
      if (!res.ok || !Array.isArray(d.scenes) || !d.scenes.length) throw new Error(d.error || "no scenes returned");
      const specs: SceneSpec[] = d.scenes.filter((s: SceneSpec) => s.template && MG_TEMPLATES[s.template]);
      if (!specs.length) throw new Error("the model returned no usable scenes — try again");
      // ONE type system for the whole sequence (user pick wins → else the AI's choice → else a cohesive default),
      // applied to every scene alongside the shared theme+accent so colors AND fonts stay consistent.
      const seqFont = font || d.font || "clean";
      setSkipped((d.dropped || 0) + (d.scenes.length - specs.length));
      setLog(specs.map((s) => ({ label: s.label || s.template, template: s.template, state: "pending" })));
      // drop them in one at a time → visible step-by-step build
      let firstId = "";
      for (let i = 0; i < specs.length; i++) {
        setLog((l) => l.map((x, j) => (j === i ? { ...x, state: "active" } : x)));
        await sleep(420);
        const id = addGeneratedScene({ ...specs[i], theme, accent, font: seqFont });
        if (!firstId) firstId = id;
        setLog((l) => l.map((x, j) => (j === i ? { ...x, state: "done" } : x)));
      }
      if (firstId) selectMotion(firstId); // open the first scene in the inspector for tweaks
      setPhase("done");
    } catch (e) {
      setErr(e instanceof Error ? e.message : String(e));
      setPhase("setup");
    }
  }

  return (
    <div className="fixed inset-0 z-50 grid place-items-center bg-black/45 p-3 sm:p-6" onClick={phase === "running" ? undefined : onClose}>
      <div className="flex max-h-[88vh] w-full min-w-0 max-w-[560px] flex-col rounded-xl border border-border bg-surface-raised shadow-2xl" onClick={(e) => e.stopPropagation()}>
        <div className="flex items-center justify-between border-b border-border px-5 py-3">
          <div className="flex items-center gap-2 font-semibold text-fg"><Sparkles size={16} className="text-primary" /> Generate motion graphics</div>
          <button onClick={onClose} className="rounded p-1 text-fg-muted hover:bg-white/5"><X size={16} /></button>
        </div>

        <div className="min-h-0 flex-1 overflow-y-auto p-5">
          {phase !== "done" ? (
            <div className="space-y-4">
              <p className="text-[13px] leading-relaxed text-fg-muted">
                The AI will design <b className="text-fg">{count}</b> scenes written about <b className="text-fg">{topic.trim() || projectName}</b> — unique to this project, then place them on your timeline. Edit any of them after.
              </p>

              <div>
                <div className="eyebrow mb-1">Topic <span className="normal-case text-fg-subtle">— defaults to the project name</span></div>
                <input value={topic} onChange={(e) => setTopic(e.target.value)} placeholder={projectName} className="w-full rounded-md border border-border bg-surface px-3 py-2 text-[13px] outline-none focus:border-primary" />
              </div>

              <div>
                <div className="eyebrow mb-1.5">Look</div>
                <div className="flex flex-wrap gap-2">
                  {MG_THEME_LIST.map((t) => (
                    <button key={t.id} onClick={() => setTheme(t.id)} title={t.label}
                      className={"flex items-center gap-2 rounded-md border px-2.5 py-1.5 text-[12px] " + (theme === t.id ? "border-primary text-fg" : "border-border text-fg-muted hover:border-primary/50")}>
                      <span className="h-4 w-4 rounded" style={{ background: t.swatch }} /> {t.label}
                    </button>
                  ))}
                </div>
              </div>

              <div>
                <div className="eyebrow mb-1.5">Accent</div>
                <div className="flex flex-wrap gap-2">
                  {MG_ACCENTS.map((c) => (
                    <button key={c} onClick={() => setAccent(c)} className={"h-7 w-7 rounded-full border-2 " + (accent.toLowerCase() === c.toLowerCase() ? "border-fg" : "border-transparent")} style={{ background: c }} />
                  ))}
                </div>
              </div>

              <div>
                <div className="eyebrow mb-1.5">Typeface <span className="normal-case text-fg-subtle">— one type system across every scene</span></div>
                <div className="flex flex-wrap gap-2">
                  <button onClick={() => setFont("")} title="Let the AI director choose the type system that best fits your topic"
                    className={"rounded-md border px-2.5 py-1.5 text-[12px] " + (font === "" ? "border-primary text-fg" : "border-border text-fg-muted hover:border-primary/50")}>
                    ✨ Auto
                  </button>
                  {FONT_PICKS.map((f) => (
                    <button key={f.id} onClick={() => setFont(f.id)} title={f.blurb} style={{ fontFamily: f.preview }}
                      className={"rounded-md border px-2.5 py-1.5 text-[12px] " + (font === f.id ? "border-primary text-fg" : "border-border text-fg-muted hover:border-primary/50")}>
                      {f.label}
                    </button>
                  ))}
                </div>
              </div>

              <div>
                <div className="eyebrow mb-1.5">Scenes · {count}</div>
                <input type="range" min={3} max={8} value={count} onChange={(e) => setCount(Number(e.target.value))} className="w-full accent-primary" />
              </div>

              <div className="flex items-center gap-1.5 text-[11px] text-fg-subtle">
                <Sparkles size={12} className="text-primary" /> Art-directed by the Eldouma AI director · {Object.keys(MG_TEMPLATES).length} cinematic templates · ~10s
              </div>

              {err && <div className="rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-[12px] text-destructive">⚠️ {err}</div>}

              {phase === "running" ? (
                <div className="space-y-1.5">
                  {log.map((s, i) => (
                    <div key={i} className="flex items-center gap-2 text-[13px]">
                      {s.state === "done" ? <Check size={14} className="text-success" /> : s.state === "active" ? <Loader2 size={14} className="animate-spin text-primary" /> : <span className="h-3.5 w-3.5 rounded-full border border-fg-subtle/40" />}
                      <span className={s.state === "pending" ? "text-fg-subtle" : "text-fg"}>{s.label}</span>
                      <span className="rounded bg-white/5 px-1 text-[10px] text-fg-muted">{s.template}</span>
                    </div>
                  ))}
                  {!log.length && <div className="flex items-center gap-2 text-[13px] text-fg-muted"><Loader2 size={14} className="animate-spin text-primary" /> Designing scenes about “{topic.trim() || projectName}”…</div>}
                </div>
              ) : (
                <button onClick={run} className="flex w-full items-center justify-center gap-2 rounded-md bg-primary py-2.5 text-[14px] font-semibold text-white hover:brightness-105">
                  <Wand2 size={15} /> Generate {count} scenes
                </button>
              )}
            </div>
          ) : (
            <div className="space-y-4 text-center">
              <div className="mx-auto grid h-12 w-12 place-items-center rounded-full bg-success/15 text-success"><Check size={26} /></div>
              <div className="text-[15px] font-semibold text-fg">Added {log.length} scenes to your timeline</div>
              {skipped > 0 && <p className="text-[12px] text-fg-subtle">({skipped} scene{skipped === 1 ? "" : "s"} from the model were unusable and skipped.)</p>}
              <p className="text-[13px] text-fg-muted">They're laid out end-to-end. The first one is open in the editor on the left — click any scene (timeline or list) to tweak its text, colors, and timing.</p>
              <div className="flex gap-2">
                <button onClick={() => setPhase("setup")} className="flex-1 rounded-md border border-border py-2 text-[13px] font-medium text-fg-muted hover:text-fg">Generate more</button>
                <button onClick={onClose} className="flex flex-1 items-center justify-center gap-1 rounded-md bg-primary py-2 text-[13px] font-semibold text-white">Start editing <ArrowRight size={14} /></button>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
