"use client";

import { useEffect, useRef, useState, type ReactNode } from "react";
import Link from "next/link";
import { Loader2, Lock, Sparkles } from "lucide-react";
import { cn } from "@/lib/utils";
import { STICKERS, STICKER_CATEGORIES, STICKER_CATEGORY_LABELS, type Sticker } from "@/lib/notes/note-stickers";
import { formatCoverPrice } from "@/lib/notes/note-covers";
import { useNoteDesignPurchases } from "@/hooks/use-note-design-purchases";

interface StickerGridProps {
  onSelect: (sticker: Sticker) => void;
}

function StickerGrid({ onSelect }: StickerGridProps) {
  const [activeCategory, setActiveCategory] = useState<Sticker["category"]>(STICKER_CATEGORIES[0]);
  const { ownsSticker, purchaseSticker, purchasingId } = useNoteDesignPurchases();
  const visible = STICKERS.filter((sticker) => sticker.category === activeCategory);

  function handleClick(sticker: Sticker) {
    if (ownsSticker(sticker)) {
      onSelect(sticker);
    } else {
      void purchaseSticker(sticker);
    }
  }

  return (
    <div className="w-64 rounded-xl border border-border bg-popover p-2.5 shadow-xl">
      <div className="mb-2 flex flex-wrap gap-1">
        {STICKER_CATEGORIES.map((category) => (
          <button
            key={category}
            type="button"
            onClick={() => setActiveCategory(category)}
            className={cn(
              "rounded-full px-2 py-0.5 text-[10.5px] font-semibold transition-colors",
              activeCategory === category
                ? "bg-accent text-accent-foreground"
                : "text-muted-foreground hover:text-foreground",
            )}
          >
            {STICKER_CATEGORY_LABELS[category]}
          </button>
        ))}
      </div>
      <div className="grid grid-cols-4 gap-1.5">
        {visible.map((sticker) => {
          const owned = ownsSticker(sticker);
          const purchasing = purchasingId === sticker.id;
          return (
            <button
              key={sticker.id}
              type="button"
              title={owned ? sticker.label : `${sticker.label} — ${formatCoverPrice(sticker.price)}`}
              onClick={() => handleClick(sticker)}
              disabled={purchasing}
              className="relative flex h-11 w-11 items-center justify-center rounded-lg text-[22px] transition-colors hover:bg-accent disabled:opacity-60"
            >
              {sticker.emoji}
              {!owned && (
                <div className="absolute inset-0 flex flex-col items-center justify-center gap-0.5 rounded-lg bg-black/60 text-white">
                  {purchasing ? (
                    <Loader2 className="h-3 w-3 animate-spin" />
                  ) : (
                    <>
                      <Lock className="h-2.5 w-2.5" />
                      <span className="text-[8px] font-semibold">{formatCoverPrice(sticker.price)}</span>
                    </>
                  )}
                </div>
              )}
            </button>
          );
        })}
      </div>
      <Link
        href="/notes/marketplace?tab=stickers"
        className="mt-2 flex items-center justify-center gap-1 border-t border-border/60 pt-2 text-[11px] font-medium text-primary hover:underline"
      >
        <Sparkles className="h-3 w-3" />
        Sticker marketplace
      </Link>
    </div>
  );
}

interface StickerPickerButtonProps {
  trigger: (open: () => void) => ReactNode;
  onSelect: (sticker: Sticker) => void;
  align?: "start" | "end";
}

export function StickerPickerButton({ trigger, onSelect, align = "start" }: StickerPickerButtonProps) {
  const [open, setOpen] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!open) return;
    function handleClick(e: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, [open]);

  return (
    <div ref={containerRef} className="relative inline-block">
      {trigger(() => setOpen(true))}
      {open && (
        <div className={cn("absolute top-full z-50 mt-1.5", align === "end" ? "right-0" : "left-0")}>
          <StickerGrid
            onSelect={(sticker) => {
              onSelect(sticker);
              setOpen(false);
            }}
          />
        </div>
      )}
    </div>
  );
}
