import { useEffect, useRef, useState } from "react";
import { X, Sparkles, Upload, Wand2, Loader2, Film, FolderOpen, Trash2, Mic, Type, Clapperboard, ClipboardPaste } from "lucide-react";
import { useStore, type ProjectManifest } from "../store";
import { scriptToWords } from "../lib/script";
import { ModelSwitcher } from "./ModelSwitcher";
import { aiHeaders } from "../lib/aiKeys";

const LENGTHS = ["~30 sec", "~1 minute", "~2 minutes"];
const TONES = ["Friendly", "Authoritative", "Cinematic", "Energetic"];

type Recent = { id: string; name: string; source: string; updatedAt?: string; words: number; assets: number };

const SOURCE_META: Record<string, { icon: typeof Type; label: string }> = {
  script: { icon: Type, label: "AI script" },
  import: { icon: Mic, label: "Imported" },
  episode: { icon: Clapperboard, label: "Demo" },
};

export function NewProjectModal({ open, onClose }: { open: boolean; onClose: () => void }) {
  const loadProject = useStore((s) => s.loadProject);
  const setView = useStore((s) => s.setView);
  const model = useStore((s) => s.model);
  const currentId = useStore((s) => s.projectId);
  const [mode, setMode] = useState<"script" | "paste" | "import" | "recent">("script");
  const [title, setTitle] = useState(""); // every project needs a title
  const [pasted, setPasted] = useState("");
  const [prompt, setPrompt] = useState("");
  const [length, setLength] = useState(LENGTHS[1]);
  const [tone, setTone] = useState(TONES[0]);
  const [script, setScript] = useState("");
  const [gen, setGen] = useState(false);
  const [autoBuild, setAutoBuild] = useState(true); // kick off the AI build right after creating (the <60s "wow")
  const [importing, setImporting] = useState("");
  const [recents, setRecents] = useState<Recent[]>([]);
  const inputRef = useRef<HTMLInputElement>(null);

  const refreshRecents = () => fetch("/api/projects").then((r) => r.json()).then((d) => setRecents(d.projects || [])).catch(() => {});
  useEffect(() => { if (open) refreshRecents(); }, [open]);

  if (!open) return null;

  async function createAndLoad(body: Record<string, unknown>, buildPrompt?: string) {
    const res = await fetch("/api/projects", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) });
    const m: ProjectManifest = await res.json();
    if (!res.ok || !m.id) return; // don't enter the editor with a broken (id-less) project
    loadProject(m);
    // hand the brief straight to the agent so the build starts on first load — no second intake form
    if (buildPrompt) useStore.getState().requestAgent(buildPrompt);
    onClose();
  }

  async function generate() {
    if (!title.trim() && prompt.trim()) setTitle(prompt.trim().split(/\s+/).slice(0, 7).join(" ")); // suggest a title from the brief
    setGen(true);
    try {
      const res = await fetch("/api/script", { method: "POST", headers: { "Content-Type": "application/json", ...aiHeaders() }, body: JSON.stringify({ prompt, model, length, tone }) });
      const d = await res.json();
      setScript(d.script || "⚠️ " + (d.error || "no script returned"));
    } catch (e) { setScript("⚠️ " + e); }
    setGen(false);
  }
  function useScript() {
    if (!title.trim() || !script.trim() || script.startsWith("⚠️")) return;
    const words = scriptToWords(script).map((w) => ({ text: w.text, startMs: w.startMs, endMs: w.endMs }));
    const build = autoBuild ? `Build this video from the script. Length: ${length}. Tone: ${tone}. Propose a section outline with treatments, then build every section in order — pick a design style and add an art-directed motion-graphics scene for each, placed on the beat it illustrates. Keep going until every section is done, then give a one-line wrap-up.` : undefined;
    createAndLoad({ name: title.trim(), words, audioSrc: "", source: "script" }, build);
  }
  function usePasted() {
    if (!title.trim() || !pasted.trim()) return;
    const words = scriptToWords(pasted).map((w) => ({ text: w.text, startMs: w.startMs, endMs: w.endMs }));
    const build = autoBuild ? `Build this video from the script. Propose a section outline with treatments, then build every section in order with art-directed motion-graphics scenes placed on the beat they illustrate. Keep going until every section is done, then give a one-line wrap-up.` : undefined;
    createAndLoad({ name: title.trim(), words, audioSrc: "", source: "script" }, build);
  }
  async function importFile(files: FileList | null) {
    const f = files?.[0];
    if (!f) return;
    let createdId: string | null = null;
    setImporting("Creating project…");
    try {
      const proj: ProjectManifest = await fetch("/api/projects", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: title.trim() || f.name.replace(/\.[^.]+$/, ""), source: "import" }) }).then((r) => r.json());
      createdId = proj.id;
      setImporting("Uploading & transcribing (Whisper)…");
      const res = await fetch(`/api/projects/${proj.id}/import?name=${encodeURIComponent(f.name)}`, { method: "POST", headers: { "Content-Type": f.type || "application/octet-stream", ...aiHeaders() }, body: f });
      const m = await res.json();
      if (!res.ok) throw new Error(m.error || "import failed");
      loadProject(m);
      onClose();
    } catch (e) {
      if (createdId) fetch(`/api/projects/${createdId}`, { method: "DELETE" }).catch(() => {}); // don't leave an empty project behind
      setImporting("⚠️ " + (e instanceof Error ? e.message : String(e)));
    }
  }
  async function openRecent(id: string) {
    const res = await fetch(`/api/projects/${id}`);
    if (!res.ok) return;
    loadProject(await res.json());
    onClose();
  }
  async function deleteRecent(id: string) {
    await fetch(`/api/projects/${id}`, { method: "DELETE" }).catch(() => {});
    if (localStorage.getItem("ed.lastProject") === id) localStorage.removeItem("ed.lastProject");
    setRecents((rs) => rs.filter((p) => p.id !== id));
    if (id === currentId) { // deleted the project that's open → fall back to the demo, or home if that fails
      const m = await fetch("/api/projects/demo", { method: "POST" }).then((r) => r.json()).catch(() => null);
      if (m && m.id) loadProject(m); else setView("home");
    }
  }

  const estSec = Math.round((scriptToWords(script).at(-1)?.endMs || 0) / 1000);
  const wordCount = script.trim() ? script.trim().split(/\s+/).filter(Boolean).length : 0;

  return (
    <div className="fixed inset-0 z-50 grid place-items-center bg-black/45 p-3 sm:p-6" onClick={onClose}>
      <div className="flex max-h-[88vh] w-full min-w-0 max-w-[620px] 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" /> New Project</div>
          <button onClick={onClose} className="rounded p-1 text-fg-muted hover:bg-white/5"><X size={16} /></button>
        </div>

        <div className="flex gap-1 overflow-x-auto px-4 pt-3 [-ms-overflow-style:none] [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
          <Tab active={mode === "script"} onClick={() => setMode("script")} icon={<Wand2 size={14} />} label="Write with AI" />
          <Tab active={mode === "paste"} onClick={() => setMode("paste")} icon={<ClipboardPaste size={14} />} label="Paste script" />
          <Tab active={mode === "import"} onClick={() => setMode("import")} icon={<Upload size={14} />} label="Import A/V" />
          <Tab active={mode === "recent"} onClick={() => setMode("recent")} icon={<FolderOpen size={14} />} label={`Recent${recents.length ? ` (${recents.length})` : ""}`} />
        </div>

        <div className="min-h-0 flex-1 overflow-y-auto p-4">
          {mode !== "recent" && (
            <div className="mb-4">
              <div className="eyebrow mb-1">Project title <span className="text-primary">*</span></div>
              <input value={title} onChange={(e) => setTitle(e.target.value)} maxLength={80} placeholder="e.g. Launch teaser — Spring 2026"
                className="w-full rounded-md border border-border bg-surface px-3 py-2.5 text-[14px] font-medium outline-none focus:border-primary" />
            </div>
          )}
          {mode === "script" ? (
            <div className="space-y-3">
              <div>
                <div className="eyebrow mb-1">What's your video about?</div>
                <textarea value={prompt} onChange={(e) => setPrompt(e.target.value)} placeholder="e.g. How AI motion graphics save editors hours — for indie creators" className="h-16 w-full resize-none rounded-md border border-border bg-surface px-3 py-2 text-[13px] outline-none focus:border-primary" />
              </div>
              <div className="flex flex-wrap gap-5">
                <ChipRow label="Length" value={length} set={setLength} options={LENGTHS} />
                <ChipRow label="Tone" value={tone} set={setTone} options={TONES} />
              </div>
              <div className="flex flex-wrap items-center gap-2">
                <ModelSwitcher />
                <span className="text-[11px] text-fg-subtle">writes the script</span>
                <div className="flex-1" />
                <button onClick={generate} disabled={gen} className="flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-[13px] font-semibold text-white disabled:opacity-50">
                  {gen ? <Loader2 size={14} className="animate-spin" /> : <Wand2 size={14} />} {script ? "Regenerate" : "Generate script"}
                </button>
              </div>
              {(script || gen) && (
                <div>
                  <div className="eyebrow mb-1">Script <span className="normal-case text-fg-subtle">— edit freely</span></div>
                  <textarea value={script} onChange={(e) => setScript(e.target.value)} placeholder={gen ? "Writing…" : ""} className="h-44 w-full resize-none rounded-md border border-border bg-surface px-3 py-2 text-[13px] leading-relaxed outline-none focus:border-primary" />
                  {wordCount > 0 && <div className="mt-1 text-[11px] text-fg-subtle">{wordCount} words · ~{estSec}s estimated</div>}
                </div>
              )}
              <AutoBuildToggle checked={autoBuild} onChange={setAutoBuild} />
              <button onClick={useScript} disabled={!title.trim() || !script.trim() || script.startsWith("⚠️")} className="w-full rounded-md bg-primary py-2.5 text-[14px] font-semibold text-white disabled:opacity-40">{!title.trim() ? "Add a project title first" : autoBuild ? "Create & build with AI →" : "Create project from script →"}</button>
              <p className="text-[11px] text-fg-subtle">Creates a project with its own asset library + saved timeline (estimated timing). Import a voiceover — or use TTS later — to lock real timing.</p>
            </div>
          ) : mode === "paste" ? (
            <div className="space-y-3">
              <div className="eyebrow mb-1">Paste your script</div>
              <textarea value={pasted} onChange={(e) => setPasted(e.target.value)} placeholder="Paste a script you already wrote — it becomes your editable transcript." className="h-56 w-full resize-none rounded-md border border-border bg-surface px-3 py-2 text-[13px] leading-relaxed outline-none focus:border-primary" />
              {pasted.trim() && <div className="text-[11px] text-fg-subtle">{pasted.trim().split(/\s+/).filter(Boolean).length} words · ~{Math.round((scriptToWords(pasted).at(-1)?.endMs || 0) / 1000)}s estimated</div>}
              <AutoBuildToggle checked={autoBuild} onChange={setAutoBuild} />
              <button onClick={usePasted} disabled={!title.trim() || !pasted.trim()} className="w-full rounded-md bg-primary py-2.5 text-[14px] font-semibold text-white disabled:opacity-40">{!title.trim() ? "Add a project title first" : autoBuild ? "Create & build with AI →" : "Create project from script →"}</button>
            </div>
          ) : mode === "import" ? (
            <div className="space-y-3">
              <button onClick={() => title.trim() && inputRef.current?.click()} disabled={!title.trim()} className="flex w-full flex-col items-center gap-2 rounded-lg border border-dashed border-border py-10 text-fg-muted hover:border-primary hover:text-fg disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:border-border disabled:hover:text-fg-muted">
                <Film size={24} />
                <span className="text-[13px] font-medium">{title.trim() ? "Import your voiceover or talking-head clip" : "Add a project title first"}</span>
                <span className="text-[11px] text-fg-subtle">A new project is created, auto-transcribed word-by-word, with its own asset library</span>
              </button>
              <input ref={inputRef} type="file" accept="audio/*,video/*" hidden onChange={(e) => importFile(e.target.files)} />
              {importing && <div className="flex items-center gap-2 text-[13px] text-fg">{!importing.startsWith("⚠️") && <Loader2 size={14} className="animate-spin text-primary" />}<span className={importing.startsWith("⚠️") ? "text-destructive" : ""}>{importing}</span></div>}
            </div>
          ) : (
            <div className="space-y-2">
              {recents.length === 0 && <div className="py-8 text-center text-[13px] text-fg-subtle">No saved projects yet. Create one from a script or an import — each gets its own folder and asset library.</div>}
              {recents.map((p) => {
                const meta = SOURCE_META[p.source] || SOURCE_META.script;
                const Icon = meta.icon;
                return (
                  <div key={p.id} className={"group flex items-center gap-3 rounded-lg border px-3 py-2.5 " + (p.id === currentId ? "border-primary bg-primary/5" : "border-border hover:border-primary/50")}>
                    <button onClick={() => openRecent(p.id)} className="flex min-w-0 flex-1 items-center gap-3 text-left">
                      <span className="grid h-9 w-9 shrink-0 place-items-center rounded-md bg-surface text-fg-muted"><Icon size={16} /></span>
                      <span className="min-w-0">
                        <span className="block truncate text-[13px] font-medium text-fg">{p.name}{p.id === currentId ? " · open" : ""}</span>
                        <span className="block truncate text-[11px] text-fg-subtle">{meta.label} · {p.words} words · {p.assets} clip{p.assets === 1 ? "" : "s"}{p.updatedAt ? ` · ${new Date(p.updatedAt).toLocaleDateString()}` : ""}</span>
                      </span>
                    </button>
                    <button onClick={() => deleteRecent(p.id)} title="Delete project" className="shrink-0 rounded p-1.5 text-fg-subtle opacity-0 transition hover:bg-white/5 hover:text-destructive group-hover:opacity-100"><Trash2 size={14} /></button>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function AutoBuildToggle({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) {
  return (
    <label className="flex cursor-pointer select-none items-center gap-2 rounded-md border border-border bg-surface px-3 py-2 text-[12.5px] text-fg-muted">
      <input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} className="h-3.5 w-3.5 accent-[#e7723b]" />
      <Sparkles size={13} className="text-primary" />
      <span>Build the scenes automatically with AI <span className="text-fg-subtle">— starts the moment the editor opens</span></span>
    </label>
  );
}
function Tab({ active, onClick, icon, label }: { active: boolean; onClick: () => void; icon: React.ReactNode; label: string }) {
  return <button onClick={onClick} className={"flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-t-md border-b-2 px-3 py-2 text-[13px] " + (active ? "border-primary font-semibold text-fg" : "border-transparent text-fg-muted hover:text-fg")}>{icon} {label}</button>;
}
function ChipRow({ label, value, set, options }: { label: string; value: string; set: (v: string) => void; options: string[] }) {
  return (
    <div>
      <div className="eyebrow mb-1">{label}</div>
      <div className="flex flex-wrap gap-1.5">
        {options.map((o) => <button key={o} onClick={() => set(o)} className={"rounded-full border px-2.5 py-1 text-[12px] " + (value === o ? "border-primary bg-primary/15 text-fg" : "border-border text-fg-muted hover:border-primary/50")}>{o}</button>)}
      </div>
    </div>
  );
}
