"use client";

import { useEffect, useMemo, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import Link from "next/link";
import {
  ArrowLeft,
  Check,
  CheckCheck,
  Crown,
  Eye,
  FileText,
  Loader2,
  Lock,
  Palette,
  Plus,
  Search,
  Settings,
  Sparkles,
} from "lucide-react";
import { cn } from "@/lib/utils";
import { createClient, getBrowserUserId } from "@/lib/supabase/client";
import { Modal } from "@/components/ui/modal";
import {
  CATEGORY_LABELS,
  NOTE_COVER_CATEGORIES,
  formatCoverPrice,
  type NoteCover,
} from "@/lib/notes/note-covers";
import { STICKERS, STICKER_CATEGORIES, STICKER_CATEGORY_LABELS, type Sticker } from "@/lib/notes/note-stickers";
import {
  CATEGORY_META as TEMPLATE_CATEGORY_META,
  NOTE_TEMPLATE_CATEGORIES,
  fillTemplatePlaceholders,
  type NoteTemplate,
} from "@/lib/notes/note-templates";
import { useNoteDesigns } from "@/hooks/use-note-designs";
import { useNoteTemplates } from "@/hooks/use-note-templates";
import { useNoteDesignPurchases } from "@/hooks/use-note-design-purchases";
import { useNotes, type NoteWithRelations } from "@/hooks/use-notes";
import { NoteDesignPreviewModal } from "@/components/notes/note-design-preview-modal";
import { CreateDesignModal } from "@/components/notes/create-design-modal";
import { MyDesignsModal } from "@/components/notes/my-designs-modal";
import { CreateTemplateModal } from "@/components/notes/create-template-modal";
import { MyTemplatesModal } from "@/components/notes/my-templates-modal";
import { TemplateContentPreview } from "@/components/notes/template-content-preview";
import { TemplateWizardModal } from "@/components/notes/template-wizard-modal";

type PriceFilter = "all" | "free" | "paid";

function matchesPriceFilter(price: number, filter: PriceFilter) {
  if (filter === "free") return price === 0;
  if (filter === "paid") return price > 0;
  return true;
}

function DesignActionMenu({
  cover,
  owned,
  purchasing,
  fullAccess,
  notes,
  notesLoading,
  onBuy,
  onApplied,
  onAppliedAll,
}: {
  cover: NoteCover;
  owned: boolean;
  purchasing: boolean;
  fullAccess: boolean;
  notes: NoteWithRelations[];
  notesLoading: boolean;
  onBuy: () => void;
  onApplied: (noteTitle: string) => void;
  onAppliedAll: (count: number) => void;
}) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState("");
  const [applyingNoteId, setApplyingNoteId] = useState<string | null>(null);
  const [confirmBulk, setConfirmBulk] = useState(false);
  const [bulkApplying, setBulkApplying] = useState(false);
  const supabase = createClient();

  const filtered = notes
    .filter((note) => (note.title || "Untitled").toLowerCase().includes(search.toLowerCase()))
    .slice(0, 30);

  async function applyTo(note: NoteWithRelations) {
    setApplyingNoteId(note.id);
    await supabase.from("notes").update({ cover_id: cover.id }).eq("id", note.id);
    setApplyingNoteId(null);
    onApplied(note.title || "Untitled");
    setOpen(false);
  }

  async function applyToAll() {
    setBulkApplying(true);
    const ids = notes.map((note) => note.id);
    if (ids.length > 0) {
      await supabase.from("notes").update({ cover_id: cover.id }).in("id", ids);
    }
    setBulkApplying(false);
    setConfirmBulk(false);
    onAppliedAll(ids.length);
    setOpen(false);
  }

  function resetAndClose() {
    setConfirmBulk(false);
    setOpen(false);
  }

  return (
    <>
      <button
        type="button"
        onClick={() => setOpen(true)}
        className={cn(
          "flex shrink-0 items-center gap-1.5 rounded-full border px-3 py-1.5 text-[11px] font-semibold transition-colors",
          owned
            ? "border-white/[0.1] bg-white/[0.05] text-white/80 hover:border-ring hover:bg-white/[0.08]"
            : "border-white/[0.1] bg-white/[0.05] text-white/80 hover:border-primary/40 hover:bg-primary/10 hover:text-primary",
        )}
      >
        {owned ? <Palette className="h-3 w-3" /> : <Lock className="h-3 w-3" />}
        {owned ? "Apply" : formatCoverPrice(cover.price)}
      </button>

      <Modal open={open} onClose={resetAndClose} className="max-w-sm overflow-hidden p-0">
        {/* Preview + cover info first, then either the notes list (owned) or
            the buy action (locked) — see what it looks like and what it
            costs before deciding anything. */}
        <div className="h-28 w-full" style={cover.style} />
        <div className="flex items-center justify-between gap-2 border-b border-border/60 px-4 py-3">
          <div className="min-w-0">
            <p className="truncate text-[14px] font-semibold">{cover.name}</p>
            <p className="text-[11.5px] text-muted-foreground">{CATEGORY_LABELS[cover.category]}</p>
          </div>
          <span className="shrink-0 rounded-full border border-emerald-500/20 bg-emerald-500/[0.08] px-2.5 py-1 text-[11px] font-semibold text-emerald-500">
            {owned ? (cover.price === 0 ? "Free" : fullAccess ? "Owner" : "Owned") : formatCoverPrice(cover.price)}
          </span>
        </div>

        {owned ? (
          <div className="p-3">
            {confirmBulk ? (
              <div className="mb-3 space-y-2 rounded-lg border border-amber-500/30 bg-amber-500/[0.08] p-3">
                <p className="text-[12.5px] text-amber-300">
                  Apply to all {notes.length} {notes.length === 1 ? "note" : "notes"}? This replaces whatever
                  cover they currently have.
                </p>
                <div className="flex gap-2">
                  <button
                    type="button"
                    onClick={() => void applyToAll()}
                    disabled={bulkApplying}
                    className="flex flex-1 items-center justify-center gap-1.5 rounded-lg bg-amber-500 px-3 py-1.5 text-[12.5px] font-semibold text-amber-950 transition-colors hover:bg-amber-400 disabled:opacity-60"
                  >
                    {bulkApplying && <Loader2 className="h-3.5 w-3.5 animate-spin" />}
                    {bulkApplying ? "Applying…" : "Confirm"}
                  </button>
                  <button
                    type="button"
                    onClick={() => setConfirmBulk(false)}
                    disabled={bulkApplying}
                    className="rounded-lg border border-border px-3 py-1.5 text-[12.5px] font-medium text-muted-foreground hover:bg-accent disabled:opacity-60"
                  >
                    Cancel
                  </button>
                </div>
              </div>
            ) : (
              <button
                type="button"
                onClick={() => setConfirmBulk(true)}
                disabled={notes.length === 0}
                className="mb-3 flex w-full items-center justify-center gap-1.5 rounded-lg border border-border bg-accent/40 px-3 py-2 text-sm font-semibold transition-colors hover:bg-accent disabled:opacity-50"
              >
                <CheckCheck className="h-4 w-4" />
                Apply to all notes ({notes.length})
              </button>
            )}

            <div className="relative">
              <Search className="pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground" />
              <input
                autoFocus
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder="…or search a single note"
                className="w-full rounded-lg border border-border bg-background py-2 pl-8 pr-2 text-sm outline-none focus:border-ring"
              />
            </div>
            <div className="mt-2 max-h-64 space-y-0.5 overflow-y-auto">
              {notesLoading ? (
                <div className="flex justify-center py-4">
                  <Loader2 className="h-4 w-4 animate-spin text-muted-foreground" />
                </div>
              ) : filtered.length === 0 ? (
                <p className="px-2 py-4 text-center text-[12px] text-muted-foreground">No notes found</p>
              ) : (
                filtered.map((note) => (
                  <button
                    key={note.id}
                    type="button"
                    onClick={() => void applyTo(note)}
                    disabled={applyingNoteId === note.id}
                    className="flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left text-sm transition-colors hover:bg-accent disabled:opacity-50"
                  >
                    <FileText className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
                    <span className="truncate">{note.title || "Untitled"}</span>
                    {applyingNoteId === note.id && <Loader2 className="ml-auto h-3.5 w-3.5 shrink-0 animate-spin" />}
                  </button>
                ))
              )}
            </div>
          </div>
        ) : (
          <div className="space-y-2.5 p-4">
            <p className="text-[12.5px] text-muted-foreground">Unlock this design once to use it on any of your notes.</p>
            <button
              type="button"
              onClick={onBuy}
              disabled={purchasing}
              className="flex w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 py-2.5 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-60"
            >
              {purchasing && <Loader2 className="h-4 w-4 animate-spin" />}
              {purchasing ? "Redirecting…" : `Unlock for ${formatCoverPrice(cover.price)}`}
            </button>
          </div>
        )}
      </Modal>
    </>
  );
}

function DesignCard({
  cover,
  owned,
  purchasing,
  fullAccess,
  notes,
  notesLoading,
  onBuy,
  onApplied,
  onAppliedAll,
  onPreview,
}: {
  cover: NoteCover;
  owned: boolean;
  purchasing: boolean;
  fullAccess: boolean;
  notes: NoteWithRelations[];
  notesLoading: boolean;
  onBuy: () => void;
  onApplied: (noteTitle: string) => void;
  onAppliedAll: (count: number) => void;
  onPreview: () => void;
}) {
  return (
    <div className="group overflow-hidden rounded-2xl border border-white/[0.07] bg-white/[0.02] transition-colors hover:border-white/[0.14]">
      <div className="relative h-28 w-full" style={cover.style}>
        {owned && (
          <div className="absolute right-2 top-2 flex h-6 w-6 items-center justify-center rounded-full bg-black/55 text-emerald-400 backdrop-blur-sm">
            <Check className="h-3.5 w-3.5" />
          </div>
        )}
        <button
          type="button"
          onClick={onPreview}
          title="Preview"
          className="absolute left-2 top-2 flex h-6 w-6 items-center justify-center rounded-full bg-black/55 text-white opacity-0 backdrop-blur-sm transition-opacity hover:bg-black/70 group-hover:opacity-100"
        >
          <Eye className="h-3.5 w-3.5" />
        </button>
      </div>
      <div className="flex items-center justify-between gap-2 p-3">
        <div className="min-w-0">
          <p className="truncate text-[13px] font-semibold text-white/85">{cover.name}</p>
          <p className="text-[11px] text-white/35">{CATEGORY_LABELS[cover.category]}</p>
        </div>

        <DesignActionMenu
          cover={cover}
          owned={owned}
          purchasing={purchasing}
          fullAccess={fullAccess}
          notes={notes}
          notesLoading={notesLoading}
          onBuy={onBuy}
          onApplied={onApplied}
          onAppliedAll={onAppliedAll}
        />
      </div>
    </div>
  );
}

function StickerCard({
  sticker,
  owned,
  purchasing,
  fullAccess,
  onBuy,
}: {
  sticker: Sticker;
  owned: boolean;
  purchasing: boolean;
  fullAccess: boolean;
  onBuy: () => void;
}) {
  return (
    <div className="flex flex-col items-center gap-2 rounded-2xl border border-white/[0.07] bg-white/[0.02] p-4 text-center transition-colors hover:border-white/[0.14]">
      <div className="flex h-16 w-16 items-center justify-center rounded-xl bg-white/[0.04] text-[32px]">
        {sticker.emoji}
      </div>
      <p className="truncate text-[12.5px] font-semibold text-white/85">{sticker.label}</p>
      {owned ? (
        <span className="rounded-full border border-emerald-500/20 bg-emerald-500/[0.08] px-2.5 py-1 text-[11px] font-semibold text-emerald-300">
          {sticker.price === 0 ? "Free" : fullAccess ? "Owner" : "Owned"}
        </span>
      ) : (
        <button
          type="button"
          onClick={onBuy}
          disabled={purchasing}
          className="flex items-center gap-1.5 rounded-full border border-white/[0.1] bg-white/[0.05] px-3 py-1.5 text-[11px] font-semibold text-white/80 transition-colors hover:border-primary/40 hover:bg-primary/10 hover:text-primary disabled:opacity-60"
        >
          {purchasing ? <Loader2 className="h-3 w-3 animate-spin" /> : <Lock className="h-3 w-3" />}
          {formatCoverPrice(sticker.price)}
        </button>
      )}
    </div>
  );
}

function TemplateActionModal({
  template,
  owned,
  purchasing,
  fullAccess,
  using,
  cover,
  purchaseCount,
  onBuy,
  onUse,
}: {
  template: NoteTemplate;
  owned: boolean;
  purchasing: boolean;
  fullAccess: boolean;
  using: boolean;
  cover: NoteCover | null;
  purchaseCount: number;
  onBuy: () => void;
  onUse: () => void;
}) {
  const [open, setOpen] = useState(false);
  const meta = TEMPLATE_CATEGORY_META[template.category];

  return (
    <>
      <button
        type="button"
        onClick={() => setOpen(true)}
        className={cn(
          "mt-1 flex items-center justify-center gap-1.5 rounded-lg border px-3 py-1.5 text-[11.5px] font-semibold transition-colors disabled:opacity-60",
          owned
            ? "border-white/[0.1] bg-white/[0.05] text-white/80 hover:border-ring hover:bg-white/[0.08]"
            : template.exclusive
              ? "border-amber-500/30 bg-amber-500/[0.1] text-amber-300 hover:bg-amber-500/[0.18]"
              : "border-white/[0.1] bg-white/[0.05] text-white/80 hover:border-primary/40 hover:bg-primary/10 hover:text-primary",
        )}
      >
        {owned ? <Eye className="h-3.5 w-3.5" /> : <Lock className="h-3.5 w-3.5" />}
        {owned ? "View & use" : formatCoverPrice(template.price)}
      </button>

      <Modal
        open={open}
        onClose={() => setOpen(false)}
        className={cn("max-w-md overflow-hidden p-0", template.exclusive && "exclusive-reveal")}
      >
        {/* Preview + price first, exactly like the cover flow — see what it
            actually contains and what it costs before doing anything. */}
        <div className={cn("h-24 w-full", !cover && "bg-muted/30")} style={cover?.style} />
        <div className="flex items-start justify-between gap-2 border-b border-border/60 px-4 py-3">
          <div className="min-w-0">
            <div className="flex items-center gap-1.5">
              <p className="truncate text-[14px] font-semibold">{template.name}</p>
              {template.exclusive && (
                <span className="flex shrink-0 items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/[0.12] px-1.5 py-0.5 text-[9.5px] font-bold uppercase tracking-wide text-amber-500">
                  <Crown className="h-2.5 w-2.5" />
                  Exclusive
                </span>
              )}
            </div>
            <p className="text-[11.5px] text-muted-foreground">{meta.label}</p>
            {purchaseCount > 0 && (
              <p className="mt-0.5 text-[11px] text-muted-foreground">
                {purchaseCount >= 3 && "🔥 Bestseller — "}
                {purchaseCount} {purchaseCount === 1 ? "person" : "people"} bought this
              </p>
            )}
          </div>
          <span className="shrink-0 rounded-full border border-emerald-500/20 bg-emerald-500/[0.08] px-2.5 py-1 text-[11px] font-semibold text-emerald-500">
            {owned ? (template.price === 0 ? "Free" : fullAccess ? "Owner" : "Owned") : formatCoverPrice(template.price)}
          </span>
        </div>

        <div className="max-h-[45vh] overflow-y-auto p-4">
          <TemplateContentPreview content={template.content} />
        </div>

        <div className="border-t border-border/60 p-4">
          {owned ? (
            <button
              type="button"
              onClick={onUse}
              disabled={using}
              className="flex w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 py-2.5 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-60"
            >
              {using && <Loader2 className="h-4 w-4 animate-spin" />}
              {using ? "Creating…" : "Use template"}
            </button>
          ) : (
            <button
              type="button"
              onClick={onBuy}
              disabled={purchasing}
              className="flex w-full items-center justify-center gap-1.5 rounded-lg bg-primary px-3 py-2.5 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-60"
            >
              {purchasing && <Loader2 className="h-4 w-4 animate-spin" />}
              {purchasing ? "Redirecting…" : `Unlock for ${formatCoverPrice(template.price)}`}
            </button>
          )}
        </div>
      </Modal>
    </>
  );
}

function TemplateCard({
  template,
  owned,
  purchasing,
  fullAccess,
  using,
  cover,
  purchaseCount,
  onBuy,
  onUse,
}: {
  template: NoteTemplate;
  owned: boolean;
  purchasing: boolean;
  fullAccess: boolean;
  using: boolean;
  cover: NoteCover | null;
  purchaseCount: number;
  onBuy: () => void;
  onUse: () => void;
}) {
  const meta = TEMPLATE_CATEGORY_META[template.category];
  return (
    <div
      className={cn(
        "group relative flex flex-col gap-2.5 overflow-hidden rounded-2xl border p-4 transition-colors",
        template.exclusive
          ? "border-amber-500/25 bg-gradient-to-b from-amber-500/[0.06] to-transparent hover:border-amber-500/40"
          : "border-white/[0.07] bg-white/[0.02] hover:border-white/[0.14]",
      )}
    >
      {template.exclusive && <div className="exclusive-shimmer" />}
      {cover && <div className="relative -mx-4 -mt-4 mb-1 h-16 overflow-hidden rounded-t-2xl" style={cover.style} />}
      <div className="flex items-center justify-between gap-2">
        <div className={cn("flex h-9 w-9 items-center justify-center rounded-full text-[18px]", meta.icon)}>
          {template.icon}
        </div>
        <div className="flex items-center gap-1.5">
          {template.exclusive && (
            <span className="flex shrink-0 items-center gap-1 rounded-full border border-amber-500/30 bg-amber-500/[0.12] px-2 py-0.5 text-[10.5px] font-bold uppercase tracking-wide text-amber-300">
              <Crown className="h-2.5 w-2.5" />
              Exclusive
            </span>
          )}
          {purchaseCount >= 3 && (
            <span className="shrink-0 rounded-full border border-orange-500/25 bg-orange-500/[0.1] px-2 py-0.5 text-[10.5px] font-semibold text-orange-300">
              🔥 Bestseller
            </span>
          )}
          {owned && (
            <span className="shrink-0 rounded-full border border-emerald-500/20 bg-emerald-500/[0.08] px-2 py-0.5 text-[10.5px] font-semibold text-emerald-300">
              {template.price === 0 ? "Free" : fullAccess ? "Owner" : "Owned"}
            </span>
          )}
        </div>
      </div>
      <div className="min-w-0">
        <p className="truncate text-[13px] font-semibold text-white/85">{template.name}</p>
        <p className="mt-0.5 line-clamp-2 text-[11.5px] leading-snug text-white/35">{template.description}</p>
        {purchaseCount > 0 && <p className="mt-1 text-[10.5px] text-white/30">{purchaseCount} {purchaseCount === 1 ? "person" : "people"} bought this</p>}
      </div>
      <TemplateActionModal
        template={template}
        owned={owned}
        purchasing={purchasing}
        fullAccess={fullAccess}
        using={using}
        cover={cover}
        purchaseCount={purchaseCount}
        onBuy={onBuy}
        onUse={onUse}
      />
    </div>
  );
}

export default function NotesMarketplacePage() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const purchasedParam = searchParams.get("purchased");
  const canceled = searchParams.get("canceled");
  const { allCovers, getCover, loading: designsLoading, refetch: refetchDesigns } = useNoteDesigns();
  const { allTemplates, loading: templatesLoading, refetch: refetchTemplates } = useNoteTemplates();
  const {
    fullAccess,
    ownsCover,
    ownsSticker,
    ownsTemplate,
    purchaseCover,
    purchaseSticker,
    purchaseTemplate,
    purchasingId,
    error,
    loading,
  } = useNoteDesignPurchases();
  const { notes, loading: notesLoading, createNote } = useNotes();
  const [appliedMessage, setAppliedMessage] = useState<string | null>(null);
  const [previewCover, setPreviewCover] = useState<NoteCover | null>(null);
  const [createOpen, setCreateOpen] = useState(false);
  const [myDesignsOpen, setMyDesignsOpen] = useState(false);
  const [createTemplateOpen, setCreateTemplateOpen] = useState(false);
  const [myTemplatesOpen, setMyTemplatesOpen] = useState(false);
  const [usingTemplateId, setUsingTemplateId] = useState<string | null>(null);
  const [wizardTemplate, setWizardTemplate] = useState<NoteTemplate | null>(null);
  const [templatePopularity, setTemplatePopularity] = useState<Record<string, number>>({});
  const initialTab = searchParams.get("tab");
  const [activeTab, setActiveTab] = useState<"covers" | "stickers" | "templates">(
    initialTab === "stickers" ? "stickers" : initialTab === "templates" ? "templates" : "covers"
  );
  const [searchQuery, setSearchQuery] = useState("");
  const [priceFilter, setPriceFilter] = useState<PriceFilter>("all");

  useEffect(() => {
    if (allTemplates.length === 0) return;
    const ids = allTemplates.map((t) => t.id).join(",");
    fetch(`/api/notes/designs/popularity?ids=${encodeURIComponent(ids)}`)
      .then((res) => res.json())
      .then((json) => setTemplatePopularity(json.counts || {}))
      .catch(() => {});
  }, [allTemplates]);

  async function scheduleTemplateReminder(
    blueprint: NonNullable<NoteTemplate["reminderBlueprint"]>,
    noteId: string,
    noteTitle: string,
  ) {
    const supabase = createClient();
    const userId = await getBrowserUserId();
    if (!userId) return;
    const days = blueprint.recurrenceRule === "weekly" ? 7 : 30;
    const remindAt = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toISOString();
    await supabase.from("reminders").insert({
      user_id: userId,
      title: blueprint.title,
      remind_at: remindAt,
      status: "scheduled",
      recurrence_rule: blueprint.recurrenceRule,
      recurrence_days: [],
      source_type: "note",
      source_id: noteId,
      source_title: noteTitle,
    });
  }

  async function finalizeUseTemplate(template: NoteTemplate, answers: Record<string, string>) {
    setUsingTemplateId(template.id);
    try {
      const content =
        Object.keys(answers).length > 0 ? fillTemplatePlaceholders(template.content, answers) : template.content;
      const note = await createNote({
        title: template.name,
        content,
        cover_id: template.coverId,
        source_template_id: template.id,
        source_template_price_cents: template.price,
      });
      if (template.reminderBlueprint) {
        await scheduleTemplateReminder(template.reminderBlueprint, note.id, note.title);
      }
      router.push(`/notes/${note.id}`);
    } finally {
      setUsingTemplateId(null);
      setWizardTemplate(null);
    }
  }

  function handleUseTemplate(template: NoteTemplate) {
    if (template.wizardQuestions && template.wizardQuestions.length > 0) {
      setWizardTemplate(template);
    } else {
      void finalizeUseTemplate(template, {});
    }
  }

  const ownedCount = useMemo(
    () => allCovers.filter((cover) => ownsCover(cover)).length,
    [allCovers, ownsCover]
  );

  function handleApplied(coverName: string, noteTitle: string) {
    setAppliedMessage(`"${coverName}" applied to "${noteTitle}".`);
  }

  function handleAppliedAll(coverName: string, count: number) {
    setAppliedMessage(`"${coverName}" applied to all ${count} ${count === 1 ? "note" : "notes"}.`);
  }

  return (
    <div className="space-y-6">
      <Link
        href="/notes"
        className="inline-flex items-center gap-1.5 text-[12.5px] font-medium text-white/40 transition-colors hover:text-white/70"
      >
        <ArrowLeft className="h-3.5 w-3.5" />
        Back to notes
      </Link>

      <div
        className="relative overflow-hidden rounded-[28px] border border-white/[0.07] bg-[#0e0c15] p-8"
        style={{
          backgroundImage:
            "radial-gradient(ellipse at 20% -30%, rgba(236,72,153,0.16) 0%, transparent 55%), radial-gradient(ellipse at 85% 110%, rgba(99,102,241,0.12) 0%, transparent 50%)",
        }}
      >
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div>
            <div className="mb-3 inline-flex items-center gap-2 rounded-full border border-pink-500/20 bg-pink-500/[0.08] px-3 py-1">
              <Sparkles className="h-3.5 w-3.5 text-pink-400" />
              <span className="text-[10px] font-bold uppercase tracking-[0.18em] text-pink-300">Design Marketplace</span>
            </div>
            <h1 className="text-[28px] font-bold tracking-tight text-white">
              Make every note look exactly how you want
            </h1>
            <p className="mt-1 max-w-xl text-[14px] text-white/40">
              {fullAccess
                ? "Owner account — every design below is already unlocked for you. Everyone else only gets 3 free designs and pays per design for the rest."
                : `3 designs are free forever. The rest unlock individually, once each — ${ownedCount}/${allCovers.length} unlocked.`}
            </p>
            {fullAccess && (
              <div className="mt-4 inline-flex items-center gap-1.5 rounded-full border border-amber-500/25 bg-amber-500/[0.08] px-3 py-1.5 text-[11px] font-semibold text-amber-300">
                <Crown className="h-3.5 w-3.5" />
                Full access
              </div>
            )}
          </div>

          <div className="flex shrink-0 flex-wrap items-center gap-2">
            {activeTab === "templates" ? (
              <>
                <button
                  type="button"
                  onClick={() => setMyTemplatesOpen(true)}
                  className="inline-flex items-center gap-2 rounded-xl border border-white/[0.1] bg-white/[0.05] px-4 py-2 text-[13px] font-bold text-white/70 transition-all hover:border-white/[0.18] hover:bg-white/[0.09] hover:text-white"
                >
                  <Settings className="h-3.5 w-3.5" />
                  My templates
                </button>
                <button
                  type="button"
                  onClick={() => setCreateTemplateOpen(true)}
                  className="inline-flex items-center gap-2 rounded-xl border border-pink-500/30 bg-pink-500/[0.15] px-4 py-2 text-[13px] font-bold text-pink-200 transition-all hover:border-pink-500/50 hover:bg-pink-500/[0.22]"
                >
                  <Plus className="h-3.5 w-3.5" />
                  Create template
                </button>
              </>
            ) : activeTab === "covers" ? (
              <>
                <button
                  type="button"
                  onClick={() => setMyDesignsOpen(true)}
                  className="inline-flex items-center gap-2 rounded-xl border border-white/[0.1] bg-white/[0.05] px-4 py-2 text-[13px] font-bold text-white/70 transition-all hover:border-white/[0.18] hover:bg-white/[0.09] hover:text-white"
                >
                  <Settings className="h-3.5 w-3.5" />
                  My designs
                </button>
                <button
                  type="button"
                  onClick={() => setCreateOpen(true)}
                  className="inline-flex items-center gap-2 rounded-xl border border-pink-500/30 bg-pink-500/[0.15] px-4 py-2 text-[13px] font-bold text-pink-200 transition-all hover:border-pink-500/50 hover:bg-pink-500/[0.22]"
                >
                  <Plus className="h-3.5 w-3.5" />
                  Create your own design
                </button>
              </>
            ) : null}
          </div>
        </div>
      </div>

      {purchasedParam && (
        <div className="rounded-xl border border-emerald-500/20 bg-emerald-500/[0.06] px-4 py-3 text-sm text-emerald-300">
          Design unlocked! Use &quot;Apply&quot; below to put it on a note.
        </div>
      )}
      {canceled && (
        <div className="rounded-xl border border-border/60 bg-muted/40 px-4 py-3 text-sm text-muted-foreground">
          Checkout canceled — no charge was made.
        </div>
      )}
      {appliedMessage && (
        <div className="flex items-center justify-between gap-3 rounded-xl border border-emerald-500/20 bg-emerald-500/[0.06] px-4 py-3 text-sm text-emerald-300">
          {appliedMessage}
          <button
            type="button"
            onClick={() => router.push("/notes")}
            className="shrink-0 text-xs font-semibold underline hover:text-emerald-200"
          >
            Open notes
          </button>
        </div>
      )}
      {error && (
        <div className="rounded-xl border border-destructive/30 bg-destructive/[0.06] px-4 py-3 text-sm text-destructive">
          {error}
        </div>
      )}

      <div className="flex flex-wrap items-center gap-2">
        <div className="flex shrink-0 rounded-xl border border-white/[0.08] bg-white/[0.03] p-1">
          {(["covers", "stickers", "templates"] as const).map((tab) => (
            <button
              key={tab}
              type="button"
              onClick={() => setActiveTab(tab)}
              className={cn(
                "rounded-lg px-3 py-1.5 text-[12.5px] font-semibold capitalize transition-colors",
                activeTab === tab ? "bg-accent text-accent-foreground" : "text-white/40 hover:text-white/70",
              )}
            >
              {tab === "covers" ? "Covers" : tab === "stickers" ? "Stickers" : "Templates"}
            </button>
          ))}
        </div>
        <div className="relative min-w-[200px] flex-1">
          <Search className="pointer-events-none absolute left-3 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-white/30" />
          <input
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder={`Search ${activeTab}…`}
            className="w-full rounded-xl border border-white/[0.08] bg-white/[0.03] py-2 pl-9 pr-3 text-[13px] text-white/80 outline-none placeholder:text-white/30 focus:border-ring"
          />
        </div>
        <select
          value={priceFilter}
          onChange={(e) => setPriceFilter(e.target.value as PriceFilter)}
          className="shrink-0 rounded-xl border border-white/[0.08] bg-white/[0.03] px-3 py-2 text-[12.5px] font-medium text-white/70 outline-none focus:border-ring"
        >
          <option value="all">All prices</option>
          <option value="free">Free</option>
          <option value="paid">Paid</option>
        </select>
      </div>

      {loading || designsLoading || (activeTab === "templates" && templatesLoading) ? (
        <div className="flex items-center justify-center py-20 text-white/30">
          <Loader2 className="h-5 w-5 animate-spin" />
        </div>
      ) : activeTab === "covers" ? (
        NOTE_COVER_CATEGORIES.map((category) => {
          const covers = allCovers.filter(
            (cover) =>
              cover.category === category &&
              matchesPriceFilter(cover.price, priceFilter) &&
              cover.name.toLowerCase().includes(searchQuery.toLowerCase()),
          );
          if (covers.length === 0) return null;
          return (
            <div key={category} className="space-y-3">
              <h2 className="text-[13px] font-semibold uppercase tracking-wide text-white/40">
                {CATEGORY_LABELS[category]}
              </h2>
              <div className={cn("grid gap-3", "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4")}>
                {covers.map((cover) => (
                  <DesignCard
                    key={cover.id}
                    cover={cover}
                    owned={ownsCover(cover)}
                    purchasing={purchasingId === cover.id}
                    fullAccess={fullAccess}
                    notes={notes}
                    notesLoading={notesLoading}
                    onBuy={() => void purchaseCover(cover)}
                    onApplied={(noteTitle) => handleApplied(cover.name, noteTitle)}
                    onAppliedAll={(count) => handleAppliedAll(cover.name, count)}
                    onPreview={() => setPreviewCover(cover)}
                  />
                ))}
              </div>
            </div>
          );
        })
      ) : activeTab === "stickers" ? (
        STICKER_CATEGORIES.map((category) => {
          const stickers = STICKERS.filter(
            (sticker) =>
              sticker.category === category &&
              matchesPriceFilter(sticker.price, priceFilter) &&
              sticker.label.toLowerCase().includes(searchQuery.toLowerCase()),
          );
          if (stickers.length === 0) return null;
          return (
            <div key={category} className="space-y-3">
              <h2 className="text-[13px] font-semibold uppercase tracking-wide text-white/40">
                {STICKER_CATEGORY_LABELS[category]}
              </h2>
              <div className={cn("grid gap-3", "grid-cols-3 sm:grid-cols-4 lg:grid-cols-6")}>
                {stickers.map((sticker) => (
                  <StickerCard
                    key={sticker.id}
                    sticker={sticker}
                    owned={ownsSticker(sticker)}
                    purchasing={purchasingId === sticker.id}
                    fullAccess={fullAccess}
                    onBuy={() => void purchaseSticker(sticker)}
                  />
                ))}
              </div>
            </div>
          );
        })
      ) : (
        <>
          {(() => {
            const exclusiveTemplates = allTemplates.filter(
              (template) =>
                template.exclusive &&
                matchesPriceFilter(template.price, priceFilter) &&
                template.name.toLowerCase().includes(searchQuery.toLowerCase()),
            );
            if (exclusiveTemplates.length === 0) return null;
            return (
              <div className="space-y-3 rounded-[22px] border border-amber-500/20 bg-gradient-to-b from-amber-500/[0.05] to-transparent p-5">
                <div className="flex items-center gap-2">
                  <Crown className="h-4 w-4 text-amber-400" />
                  <h2 className="text-[13px] font-bold uppercase tracking-wide text-amber-300">
                    Exclusive Collection
                  </h2>
                  <span className="text-[11.5px] text-white/40">— flagship templates with a bundled custom cover</span>
                </div>
                <div className={cn("grid gap-3", "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4")}>
                  {exclusiveTemplates.map((template) => (
                    <TemplateCard
                      key={template.id}
                      template={template}
                      owned={ownsTemplate(template)}
                      purchasing={purchasingId === template.id}
                      fullAccess={fullAccess}
                      using={usingTemplateId === template.id}
                      cover={getCover(template.coverId)}
                      purchaseCount={templatePopularity[template.id] || 0}
                      onBuy={() => void purchaseTemplate(template)}
                      onUse={() => handleUseTemplate(template)}
                    />
                  ))}
                </div>
              </div>
            );
          })()}

          {NOTE_TEMPLATE_CATEGORIES.map((category) => {
            const templates = allTemplates.filter(
              (template) =>
                !template.exclusive &&
                template.category === category &&
                matchesPriceFilter(template.price, priceFilter) &&
                template.name.toLowerCase().includes(searchQuery.toLowerCase()),
            );
            if (templates.length === 0) return null;
            return (
              <div key={category} className="space-y-3">
                <h2 className="text-[13px] font-semibold uppercase tracking-wide text-white/40">
                  {TEMPLATE_CATEGORY_META[category].label}
                </h2>
                <div className={cn("grid gap-3", "grid-cols-2 sm:grid-cols-3 lg:grid-cols-4")}>
                  {templates.map((template) => (
                    <TemplateCard
                      key={template.id}
                      template={template}
                      owned={ownsTemplate(template)}
                      purchasing={purchasingId === template.id}
                      fullAccess={fullAccess}
                      using={usingTemplateId === template.id}
                      cover={getCover(template.coverId)}
                      purchaseCount={templatePopularity[template.id] || 0}
                      onBuy={() => void purchaseTemplate(template)}
                      onUse={() => handleUseTemplate(template)}
                    />
                  ))}
                </div>
              </div>
            );
          })}
        </>
      )}

      <NoteDesignPreviewModal cover={previewCover} open={!!previewCover} onClose={() => setPreviewCover(null)} />
      <TemplateWizardModal
        template={wizardTemplate}
        open={!!wizardTemplate}
        submitting={!!wizardTemplate && usingTemplateId === wizardTemplate.id}
        onClose={() => setWizardTemplate(null)}
        onSubmit={(answers) => {
          if (wizardTemplate) void finalizeUseTemplate(wizardTemplate, answers);
        }}
      />
      <CreateDesignModal open={createOpen} onClose={() => setCreateOpen(false)} onCreated={() => void refetchDesigns()} />
      <MyDesignsModal open={myDesignsOpen} onClose={() => setMyDesignsOpen(false)} onChanged={() => void refetchDesigns()} />
      <CreateTemplateModal
        open={createTemplateOpen}
        onClose={() => setCreateTemplateOpen(false)}
        onCreated={() => void refetchTemplates()}
      />
      <MyTemplatesModal
        open={myTemplatesOpen}
        onClose={() => setMyTemplatesOpen(false)}
        onChanged={() => void refetchTemplates()}
      />
    </div>
  );
}
