import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useEffect, useMemo, useState } from "react";
import { useServerFn } from "@tanstack/react-start";
import { ArrowLeft, Camera, Check, Loader2, Search, Sparkles, X } from "lucide-react";
import { listPrompts, type PromptRow } from "@/lib/prompts.functions";
import { saveExtraPrompts } from "@/lib/photoshoot-store";
import { EMOTIONS, EVENT_TYPES, PERSONALITIES, STYLES } from "@/lib/photoshoot-data";
import { toast } from "sonner";

export const Route = createFileRoute("/prompts")({
  head: () => ({
    meta: [
      { title: "Prompt Library — Personal Photoshoot Studio™" },
      { name: "description", content: "Browse curated AI photography prompts. Mix multiple prompts into your photoshoot plan." },
    ],
  }),
  component: PromptsPage,
});

const AI_TOOLS = ["Any", "ChatGPT", "Midjourney", "Flux", "Ideogram"] as const;

function PromptsPage() {
  const navigate = useNavigate();
  const listFn = useServerFn(listPrompts);
  const [rows, setRows] = useState<PromptRow[] | null>(null);
  const [loading, setLoading] = useState(false);
  const [q, setQ] = useState("");
  const [category, setCategory] = useState<string>("");
  const [emotion, setEmotion] = useState<string>("");
  const [personality, setPersonality] = useState<string>("");
  const [style, setStyle] = useState<string>("");
  const [aiTool, setAiTool] = useState<string>("Any");
  const [selected, setSelected] = useState<Record<string, PromptRow>>({});

  async function load() {
    setLoading(true);
    try {
      const data = await listFn({
        data: {
          q: q || undefined,
          category: category || undefined,
          emotion: emotion || undefined,
          personality: personality || undefined,
          style: style || undefined,
          ai_tool: aiTool,
          limit: 200,
        },
      });
      setRows(data);
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Failed to load prompts");
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    void load();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const selectedList = useMemo(() => Object.values(selected), [selected]);

  function toggle(p: PromptRow) {
    setSelected((s) => {
      const next = { ...s };
      if (next[p.id]) delete next[p.id];
      else next[p.id] = p;
      return next;
    });
  }

  function useInPlan() {
    if (selectedList.length === 0) {
      toast.info("Select at least one prompt to inject");
      return;
    }
    saveExtraPrompts(
      selectedList.map((p) => ({ id: p.id, title: p.title, prompt_text: p.prompt_text })),
    );
    toast.success(`${selectedList.length} prompt${selectedList.length === 1 ? "" : "s"} injected — continue to the wizard`);
    navigate({ to: "/create" });
  }

  return (
    <div className="min-h-screen bg-background">
      <header className="border-b border-border bg-background/80 backdrop-blur sticky top-0 z-30">
        <div className="mx-auto max-w-7xl px-6 h-16 flex items-center justify-between">
          <Link to="/" className="flex items-center gap-2">
            <div className="h-8 w-8 rounded-full bg-gradient-gold flex items-center justify-center">
              <Camera className="h-4 w-4 text-primary" />
            </div>
            <span className="font-display text-lg font-semibold">
              Personal Photoshoot Studio<span className="text-gold">™</span>
            </span>
          </Link>
          <Link to="/" className="text-sm text-muted-foreground hover:text-foreground inline-flex items-center gap-1.5">
            <ArrowLeft className="h-4 w-4" /> Home
          </Link>
        </div>
      </header>

      <main className="mx-auto max-w-7xl px-6 py-12">
        <div className="mb-10 max-w-3xl">
          <p className="text-xs uppercase tracking-[0.3em] text-gold mb-3">Prompt Library</p>
          <h1 className="font-display text-4xl md:text-5xl leading-tight">A curated archive of AI photography prompts.</h1>
          <p className="mt-4 text-muted-foreground text-lg">
            Browse, filter, and pick the prompts that resonate. Selected prompts are injected into your photoshoot generator as additional creative direction.
          </p>
        </div>

        {/* Filters */}
        <div className="rounded-2xl border border-border bg-card p-5 mb-8 space-y-4">
          <div className="grid md:grid-cols-[1fr_auto] gap-3">
            <div className="relative">
              <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <input
                value={q}
                onChange={(e) => setQ(e.target.value)}
                onKeyDown={(e) => e.key === "Enter" && load()}
                placeholder="Search prompts…"
                className="w-full rounded-lg border border-input bg-background pl-10 pr-3 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring/40"
              />
            </div>
            <button
              onClick={load}
              className="inline-flex items-center justify-center gap-2 rounded-lg bg-primary px-5 py-2.5 text-sm font-medium text-primary-foreground hover:opacity-90"
            >
              {loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Search className="h-4 w-4" />}
              Search
            </button>
          </div>

          <div className="grid sm:grid-cols-2 lg:grid-cols-5 gap-3">
            <FilterSelect label="Category" value={category} onChange={setCategory} options={["", ...EVENT_TYPES]} />
            <FilterSelect label="Emotion" value={emotion} onChange={setEmotion} options={["", ...EMOTIONS]} />
            <FilterSelect label="Personality" value={personality} onChange={setPersonality} options={["", ...PERSONALITIES]} />
            <FilterSelect label="Style" value={style} onChange={setStyle} options={["", ...STYLES]} />
            <FilterSelect label="AI Tool" value={aiTool} onChange={setAiTool} options={[...AI_TOOLS]} />
          </div>

          <div className="flex justify-end">
            <button
              onClick={() => {
                setQ(""); setCategory(""); setEmotion(""); setPersonality(""); setStyle(""); setAiTool("Any");
                setTimeout(load, 0);
              }}
              className="text-xs uppercase tracking-[0.2em] text-muted-foreground hover:text-foreground"
            >
              Reset filters
            </button>
          </div>
        </div>

        {/* Grid */}
        {rows === null || loading ? (
          <div className="py-24 text-center text-muted-foreground"><Loader2 className="h-6 w-6 animate-spin mx-auto" /></div>
        ) : rows.length === 0 ? (
          <div className="py-24 text-center text-muted-foreground">
            <p>No prompts found.</p>
            <p className="text-sm mt-2">Try clearing filters, or visit the admin page to add your library.</p>
          </div>
        ) : (
          <div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-5">
            {rows.map((p) => {
              const isSel = !!selected[p.id];
              return (
                <button
                  key={p.id}
                  onClick={() => toggle(p)}
                  className={`text-left rounded-2xl border p-5 transition shadow-soft hover:shadow-elegant ${isSel ? "border-gold ring-2 ring-gold/40 bg-gradient-warm" : "border-border bg-card hover:border-gold/60"}`}
                >
                  <div className="flex items-start justify-between gap-3 mb-2">
                    <h3 className="font-display text-xl leading-tight">{p.title}</h3>
                    <span className={`shrink-0 grid place-content-center h-6 w-6 rounded-full border ${isSel ? "bg-primary border-primary text-primary-foreground" : "border-border bg-background"}`}>
                      {isSel && <Check className="h-3.5 w-3.5" />}
                    </span>
                  </div>
                  <p className="text-sm text-muted-foreground leading-relaxed line-clamp-4 mb-4">{p.prompt_text}</p>
                  <div className="flex flex-wrap gap-1.5">
                    {p.category && <Tag>{p.category}</Tag>}
                    <Tag tone="gold">{p.ai_tool}</Tag>
                    {p.emotion_tags.slice(0, 2).map((t) => <Tag key={`e${t}`}>{t}</Tag>)}
                    {p.style_tags.slice(0, 2).map((t) => <Tag key={`s${t}`}>{t}</Tag>)}
                  </div>
                </button>
              );
            })}
          </div>
        )}
      </main>

      {/* Selection bar */}
      {selectedList.length > 0 && (
        <div className="fixed bottom-6 left-1/2 -translate-x-1/2 z-40 w-[calc(100%-2rem)] max-w-2xl">
          <div className="rounded-full border border-border bg-card/95 backdrop-blur shadow-elegant px-5 py-3 flex items-center gap-4">
            <span className="text-sm font-medium">
              {selectedList.length} prompt{selectedList.length === 1 ? "" : "s"} selected
            </span>
            <button onClick={() => setSelected({})} className="text-xs text-muted-foreground hover:text-foreground inline-flex items-center gap-1">
              <X className="h-3 w-3" /> Clear
            </button>
            <div className="flex-1" />
            <button
              onClick={useInPlan}
              className="inline-flex items-center gap-2 rounded-full bg-primary px-5 py-2 text-sm font-medium text-primary-foreground hover:opacity-90"
            >
              <Sparkles className="h-4 w-4" /> Use in plan
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

function FilterSelect({ label, value, onChange, options }: { label: string; value: string; onChange: (v: string) => void; options: readonly string[] }) {
  return (
    <label className="block">
      <span className="block text-[10px] uppercase tracking-[0.2em] text-muted-foreground mb-1">{label}</span>
      <select
        value={value}
        onChange={(e) => onChange(e.target.value)}
        className="w-full rounded-lg border border-input bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-ring/40"
      >
        {options.map((o) => (
          <option key={o} value={o}>{o === "" ? "All" : o}</option>
        ))}
      </select>
    </label>
  );
}

function Tag({ children, tone }: { children: React.ReactNode; tone?: "gold" }) {
  return (
    <span className={`text-[10px] uppercase tracking-[0.15em] px-2 py-0.5 rounded-full border ${tone === "gold" ? "border-gold/50 text-gold bg-background/50" : "border-border text-muted-foreground bg-background/50"}`}>
      {children}
    </span>
  );
}
