"use client";

import { useState, useEffect, useRef } from "react";
import { Card, CardContent } from "./ui/card";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
import { SOUND_CATEGORIES, EMOJIS } from "@/lib/bingo-data";
import { Badge } from "./ui/badge";

type Item = {
  id: string;
  text: string;
  emoji: string;
  soundCategory: string;
  soundUrl?: string | null;
  gridIndex: number;
};

type Campaign = {
  id: string;
  name: string;
  gridSize: number;
};

function EmojiPicker({ value, onChange }: { value: string; onChange: (v: string) => void }) {
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);

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

  return (
    <div ref={ref} className="relative">
      <button
        type="button"
        onClick={() => setOpen(!open)}
        className="w-10 h-10 flex items-center justify-center text-xl rounded border border-slate-700/50 bg-slate-800/50 hover:bg-slate-700/50 cursor-pointer"
      >
        {value || "?"}
      </button>
      {open && (
        <div className="absolute top-full left-0 mt-1 z-50 bg-slate-900 border border-slate-700/50 rounded-lg p-2 shadow-xl w-[280px]">
          <div className="grid grid-cols-8 gap-1">
            {EMOJIS.map(e => (
              <button
                key={e}
                type="button"
                onClick={() => { onChange(e); setOpen(false); }}
                className={`w-8 h-8 flex items-center justify-center text-base rounded hover:bg-slate-700 cursor-pointer ${e === value ? "bg-cyan-700/50 ring-1 ring-cyan-400" : ""}`}
              >
                {e}
              </button>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

export function ItemEditor({ campaign }: { campaign: Campaign }) {
  const [items, setItems] = useState<Item[]>([]);
  const [loading, setLoading] = useState(true);
  const [editItemId, setEditItemId] = useState<string | null>(null);
  const [editText, setEditText] = useState("");
  const [editEmoji, setEditEmoji] = useState("💀");
  const [editSound, setEditSound] = useState("horn");
  const [editSoundUrl, setEditSoundUrl] = useState<string | null>(null);
  const [uploading, setUploading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);
  const formRef = useRef<HTMLDivElement>(null);

  const fetchItems = async () => {
    const res = await fetch(`/api/campaigns/${campaign.id}/items`);
    const data = await res.json();
    const sorted = [...data].sort((a: Item, b: Item) => a.gridIndex - b.gridIndex);
    setItems(sorted);
    setLoading(false);
  };

  useEffect(() => { fetchItems(); }, [campaign.id]);

  const updateItem = async (item: Item) => {
    await fetch(`/api/campaigns/${campaign.id}/items`, {
      method: "PUT",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        id: item.id,
        text: item.text,
        emoji: item.emoji,
        soundCategory: item.soundCategory,
        soundUrl: item.soundUrl,
        gridIndex: item.gridIndex,
      }),
    });
    await fetchItems();
  };

  const deleteItem = async (itemId: string) => {
    if (editItemId === itemId) resetForm();
    await fetch(`/api/campaigns/${campaign.id}/items?itemId=${itemId}`, { method: "DELETE" });
    await fetchItems();
  };

  const addItem = async () => {
    if (!editText) return;
    const maxIdx = items.reduce((max, it) => Math.max(max, it.gridIndex), -1);
    const totalCells = campaign.gridSize * campaign.gridSize;
    if (maxIdx + 1 >= totalCells) {
      alert("Grid is full! Delete some items first.");
      return;
    }
    await fetch(`/api/campaigns/${campaign.id}/items`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        text: editText,
        emoji: editEmoji,
        soundCategory: editSound,
        soundUrl: editSoundUrl,
        gridIndex: maxIdx + 1,
      }),
    });
    resetForm();
    await fetchItems();
  };

  const submitItem = async () => {
    if (!editText) return;
    if (editItemId) {
      const existing = items.find(it => it.id === editItemId);
      if (existing) {
        await updateItem({
          ...existing,
          text: editText,
          emoji: editEmoji,
          soundCategory: editSound,
          soundUrl: editSoundUrl,
        });
      }
      resetForm();
    } else {
      await addItem();
    }
  };

  const editItem = (item: Item) => {
    setEditItemId(item.id);
    setEditText(item.text);
    setEditEmoji(item.emoji);
    setEditSound(item.soundCategory);
    setEditSoundUrl(item.soundUrl || null);
    formRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
  };

  const resetForm = () => {
    setEditItemId(null);
    setEditText("");
    setEditEmoji("💀");
    setEditSound("horn");
    setEditSoundUrl(null);
    if (fileInputRef.current) fileInputRef.current.value = "";
  };

  const uploadSound = async (file: File) => {
    setUploading(true);
    const formData = new FormData();
    formData.append("file", file);
    const res = await fetch("/api/upload/sound", { method: "POST", body: formData });
    const data = await res.json();
    if (data.url) setEditSoundUrl(data.url);
    setUploading(false);
  };

  const playSoundOnce = (url: string) => {
    try { const a = new Audio(url); a.preload = "auto"; a.volume = 0.4; a.play().catch(() => {}); } catch {}
  };

  const totalCells = campaign.gridSize * campaign.gridSize;

  if (loading) {
    return <div className="text-center text-slate-500 font-mono text-sm py-8">Loading items...</div>;
  }

  return (
    <div className="space-y-4">
      <div ref={formRef}>
        <Card className={editItemId ? "border-amber-500/40" : "border-cyan-800/30"}>
          <CardContent className="p-4 space-y-3">
            <div className="flex items-center justify-between">
              <h3 className="text-xs font-mono text-cyan-400 uppercase">{editItemId ? "✏ Edit Cell" : "+ Add New Cell"}</h3>
              {editItemId && (
                <button onClick={resetForm} className="text-[10px] font-mono text-slate-500 hover:text-slate-300 cursor-pointer">
                  Cancel
                </button>
              )}
            </div>
            <div className="flex flex-wrap gap-2 items-end">
              <div className="flex-1 min-w-[150px]">
                <label className="text-[9px] font-mono text-slate-600 uppercase">Text</label>
                <Input
                  placeholder="Reactor explodes"
                  value={editText}
                  onChange={e => setEditText(e.target.value)}
                  className="font-mono text-sm"
                />
              </div>
              <div>
                <label className="text-[9px] font-mono text-slate-600 uppercase">Emoji</label>
                <EmojiPicker value={editEmoji} onChange={setEditEmoji} />
              </div>
              <div className="w-32">
                <label className="text-[9px] font-mono text-slate-600 uppercase">Sound</label>
                <Select
                  value={editSound}
                  onValueChange={v => { setEditSound(v); if (v !== "custom") setEditSoundUrl(null); }}
                >
                  <SelectTrigger className="font-mono text-xs">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {SOUND_CATEGORIES.map(cat => (
                      <SelectItem key={cat.value} value={cat.value} className="font-mono text-xs">
                        {cat.label}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              {editSound === "custom" && (
                <div>
                  <label className="text-[9px] font-mono text-slate-600 uppercase">File</label>
                  <div className="flex gap-1 items-center">
                    <input
                      ref={fileInputRef}
                      type="file"
                      accept=".ogg"
                      className="hidden"
                      onChange={e => { const f = e.target.files?.[0]; if (f) uploadSound(f); }}
                    />
                    <Button
                      variant="outline"
                      size="sm"
                      className="font-mono text-[9px] h-10"
                      onClick={() => fileInputRef.current?.click()}
                      disabled={uploading}
                    >
                      {uploading ? "..." : editSoundUrl ? "✓" : "OGG"}
                    </Button>
                    {editSoundUrl && (
                      <button
                        type="button"
                        onClick={() => playSoundOnce(editSoundUrl)}
                        className="text-sm cursor-pointer hover:text-cyan-300"
                      >
                        ▶
                      </button>
                    )}
                  </div>
                </div>
              )}
              <Button size="sm" onClick={submitItem} disabled={!editText} className="font-mono text-xs">
                {editItemId ? "SAVE" : "ADD"}
              </Button>
            </div>
          </CardContent>
        </Card>
      </div>

      <div
        className="grid gap-1"
        style={{ gridTemplateColumns: `repeat(${campaign.gridSize}, 1fr)` }}
      >
        {Array.from({ length: totalCells }).map((_, idx) => {
          const item = items.find(it => it.gridIndex === idx);
          if (!item) {
            return (
              <div key={idx} className="aspect-square rounded border border-dashed border-slate-700/20 bg-slate-900/20 flex items-center justify-center text-slate-700 text-[10px] font-mono">
                ✖
              </div>
            );
          }
          const isEditing = editItemId === item.id;
          return (
            <Card key={item.id} className={"border-slate-700/30 aspect-square group" + (isEditing ? " ring-2 ring-amber-500/50" : "")}>
              <CardContent className="p-1.5 h-full flex flex-col items-center justify-center gap-0.5 relative">
                <span className="text-lg">{item.emoji}</span>
                <span className="text-[10px] text-center font-mono text-slate-300 leading-tight line-clamp-3 px-0.5">
                  {item.text}
                </span>
                <Badge variant="outline" className="text-[8px] px-1 py-0 absolute top-0.5 right-0.5">
                  {item.soundUrl ? "🔊" : item.soundCategory}
                </Badge>
                <div className="absolute bottom-0.5 left-0.5 right-0.5 flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
                  <Button
                    variant="secondary"
                    size="sm"
                    className="h-4 text-[8px] px-1 py-0 flex-1"
                    onClick={() => editItem(item)}
                  >
                    ✏
                  </Button>
                  <Button
                    variant="destructive"
                    size="sm"
                    className="h-4 text-[8px] px-1 py-0 flex-1"
                    onClick={() => deleteItem(item.id)}
                  >
                    ✕
                  </Button>
                </div>
                {item.soundUrl && (
                  <button
                    type="button"
                    onClick={e => { e.stopPropagation(); playSoundOnce(item.soundUrl!); }}
                    className="absolute bottom-0.5 left-0.5 text-[10px] text-cyan-500/60 hover:text-cyan-300 cursor-pointer opacity-0 group-hover:opacity-100 transition-opacity"
                  >
                    🔊
                  </button>
                )}
              </CardContent>
            </Card>
          );
        })}
      </div>

      <div className="space-y-1">
        <h4 className="text-[10px] font-mono text-slate-600 uppercase">All Items</h4>
        {items.map(item => (
          <div key={item.id} className="flex items-center gap-2 bg-slate-800/30 rounded p-2 border border-slate-700/20">
            <span className="text-sm w-6">{item.emoji}</span>
            <input
              className="flex-1 bg-transparent text-xs font-mono text-slate-200 border-b border-slate-700/30 focus:border-cyan-500/50 outline-none px-1"
              value={item.text}
              onChange={e => {
                setItems(prev => prev.map(it => it.id === item.id ? { ...it, text: e.target.value } : it));
              }}
              onBlur={() => updateItem(item)}
            />
            <Select
              value={item.soundCategory}
              onValueChange={val => {
                const updated = { ...item, soundCategory: val, soundUrl: val !== "custom" ? null : item.soundUrl };
                setItems(prev => prev.map(it => it.id === item.id ? updated : it));
                updateItem(updated);
              }}
            >
              <SelectTrigger className="h-6 text-[9px] w-20 font-mono">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                {SOUND_CATEGORIES.map(cat => (
                  <SelectItem key={cat.value} value={cat.value} className="text-[10px] font-mono">
                    {cat.label}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            <span className="text-[9px] text-slate-600 font-mono w-6 text-right">#{item.gridIndex}</span>
          </div>
        ))}
      </div>
    </div>
  );
}


