"use client";

import { useState, useEffect, useCallback } from "react";
import { Brain, Plus, Pencil, Trash2, Check, X, AlertTriangle, Layers, Pin } from "lucide-react";
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
} from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { cn } from "@/lib/utils";
import {
  fetchMemories,
  createMemory,
  updateMemory,
  deleteMemory,
  clearAllMemories,
  toggleMemoryPin,
  fetchMemorySettings,
  updateMemorySettings,
  type MemoryItem,
  type MemoryCategory,
  type MemorySettings,
} from "@/lib/api/memory";

type MemoryPanelProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

const CATEGORY_STYLES: Record<MemoryCategory, { bg: string; text: string; label: string }> = {
  preference: { bg: "bg-blue-500/10 border-blue-500/20", text: "text-blue-400", label: "Preference" },
  context: { bg: "bg-emerald-500/10 border-emerald-500/20", text: "text-emerald-400", label: "Context" },
  pattern: { bg: "bg-purple-500/10 border-purple-500/20", text: "text-purple-400", label: "Pattern" },
  fact: { bg: "bg-amber-500/10 border-amber-500/20", text: "text-amber-400", label: "Fact" },
};

const CATEGORIES: MemoryCategory[] = ["preference", "context", "pattern", "fact"];

export function MemoryPanel({ open, onOpenChange }: MemoryPanelProps) {
  const [memories, setMemories] = useState<MemoryItem[]>([]);
  const [settings, setSettings] = useState<MemorySettings | null>(null);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editContent, setEditContent] = useState("");
  const [editCategory, setEditCategory] = useState<MemoryCategory>("fact");
  const [adding, setAdding] = useState(false);
  const [newContent, setNewContent] = useState("");
  const [newCategory, setNewCategory] = useState<MemoryCategory>("fact");
  const [confirmClear, setConfirmClear] = useState(false);

  const loadData = useCallback(async () => {
    try {
      const [mems, sets] = await Promise.all([
        fetchMemories().catch(() => [] as MemoryItem[]),
        fetchMemorySettings().catch(() => null),
      ]);
      setMemories(mems);
      if (sets) setSettings(sets);
    } catch {
      // Backend not reachable — silently ignore
    }
  }, []);

  useEffect(() => {
    if (open) {
      loadData();
      setConfirmClear(false);
      const interval = setInterval(loadData, 10_000);
      return () => clearInterval(interval);
    }
  }, [open, loadData]);

  const handleToggle = async (enabled: boolean) => {
    try {
      const updated = await updateMemorySettings({ enabled });
      setSettings(updated);
    } catch (e) {
      console.error("Failed to toggle memory:", e);
    }
  };

  const handleAdd = async () => {
    if (!newContent.trim()) return;
    try {
      await createMemory(newContent.trim(), newCategory);
      setNewContent("");
      setNewCategory("fact");
      setAdding(false);
      loadData();
    } catch (e) {
      console.error("Failed to create memory:", e);
    }
  };

  const handleUpdate = async (id: string) => {
    if (!editContent.trim()) return;
    try {
      await updateMemory(id, { content: editContent.trim(), category: editCategory });
      setEditingId(null);
      loadData();
    } catch (e) {
      console.error("Failed to update memory:", e);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await deleteMemory(id);
      loadData();
    } catch (e) {
      console.error("Failed to delete memory:", e);
    }
  };

  const handleClearAll = async () => {
    try {
      await clearAllMemories();
      setConfirmClear(false);
      loadData();
    } catch (e) {
      console.error("Failed to clear memories:", e);
    }
  };

  const handleTogglePin = async (id: string) => {
    try {
      await toggleMemoryPin(id);
      loadData();
    } catch (e) {
      console.error("Failed to toggle pin:", e);
    }
  };

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent
        side="right"
        className="w-[380px] sm:max-w-[380px] bg-background/95 backdrop-blur-2xl border-foreground/10 p-0 flex flex-col"
        showCloseButton={false}
      >
        <SheetHeader className="px-5 pt-5 pb-3 border-b border-foreground/5">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-3">
              <div className="p-2 bg-purple-500/10 rounded-xl border border-purple-500/20">
                <Brain className="w-4 h-4 text-purple-400" />
              </div>
              <div>
                <SheetTitle className="text-xs font-black uppercase tracking-[0.2em] text-foreground/90">
                  Memory Bank
                </SheetTitle>
                <SheetDescription className="text-[9px] font-bold uppercase tracking-widest text-muted-foreground/50 mt-0.5">
                  {settings ? `${memories.length}/${settings.max_memories}` : memories.length} memor{memories.length !== 1 ? "ies" : "y"} stored
                </SheetDescription>
              </div>
            </div>
            {settings && (
              <Switch
                checked={settings.enabled}
                onCheckedChange={handleToggle}
                className="data-[state=checked]:bg-purple-500"
              />
            )}
          </div>
        </SheetHeader>

        {/* Add button / form */}
        <div className="px-4 py-3 border-b border-foreground/5">
          {adding ? (
            <div className="space-y-2">
              <Input
                value={newContent}
                onChange={(e) => setNewContent(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") handleAdd();
                  if (e.key === "Escape") setAdding(false);
                }}
                placeholder="Enter a memory..."
                className="h-9 text-xs border-foreground/10 bg-foreground/5"
                autoFocus
              />
              <div className="flex items-center gap-2">
                <div className="flex gap-1 flex-1">
                  {CATEGORIES.map((cat) => {
                    const style = CATEGORY_STYLES[cat];
                    return (
                      <button
                        key={cat}
                        onClick={() => setNewCategory(cat)}
                        className={cn(
                          "px-2 py-0.5 rounded-full text-[9px] font-black uppercase tracking-wider border transition-all",
                          newCategory === cat
                            ? `${style.bg} ${style.text} border-current`
                            : "bg-foreground/5 text-muted-foreground/50 border-transparent hover:bg-foreground/10"
                        )}
                      >
                        {style.label}
                      </button>
                    );
                  })}
                </div>
                <Button
                  variant="ghost" size="icon"
                  className="h-7 w-7 text-emerald-400 hover:text-emerald-300"
                  onClick={handleAdd}
                >
                  <Check className="w-3.5 h-3.5" />
                </Button>
                <Button
                  variant="ghost" size="icon"
                  className="h-7 w-7 text-muted-foreground hover:text-foreground"
                  onClick={() => setAdding(false)}
                >
                  <X className="w-3.5 h-3.5" />
                </Button>
              </div>
            </div>
          ) : (
            <div className="flex items-center gap-2">
              <Button
                variant="ghost"
                size="sm"
                onClick={() => setAdding(true)}
                className="flex-1 h-8 gap-1.5 rounded-full text-[10px] font-black uppercase tracking-wider text-purple-400 hover:text-purple-300 hover:bg-purple-500/10 justify-start"
              >
                <Plus className="w-3.5 h-3.5" />
                Add Memory
              </Button>
              {memories.length > 0 && (
                confirmClear ? (
                  <div className="flex items-center gap-1">
                    <span className="text-[9px] text-red-400 font-bold">Clear all?</span>
                    <Button
                      variant="ghost" size="icon"
                      className="h-6 w-6 text-red-400 hover:text-red-300"
                      onClick={handleClearAll}
                    >
                      <Check className="w-3 h-3" />
                    </Button>
                    <Button
                      variant="ghost" size="icon"
                      className="h-6 w-6 text-muted-foreground hover:text-foreground"
                      onClick={() => setConfirmClear(false)}
                    >
                      <X className="w-3 h-3" />
                    </Button>
                  </div>
                ) : (
                  <Button
                    variant="ghost" size="icon"
                    className="h-7 w-7 text-muted-foreground/30 hover:text-red-400"
                    onClick={() => setConfirmClear(true)}
                    title="Clear all memories"
                  >
                    <Trash2 className="w-3.5 h-3.5" />
                  </Button>
                )
              )}
            </div>
          )}
        </div>

        {/* Memory list */}
        <div className="flex-1 overflow-y-auto px-3 py-3 space-y-2">
          {settings && !settings.enabled && (
            <div className="flex items-center gap-3 p-3 rounded-xl bg-amber-500/5 border border-amber-500/10">
              <AlertTriangle className="w-4 h-4 text-amber-400 shrink-0" />
              <span className="text-[10px] font-bold text-amber-400/80">Memory is disabled. Enable to auto-extract memories from conversations.</span>
            </div>
          )}

          {settings && settings.enabled && memories.length >= settings.max_memories && (
            <div className="flex items-start gap-3 p-3 rounded-xl bg-red-500/5 border border-red-500/10">
              <AlertTriangle className="w-4 h-4 text-red-400 shrink-0 mt-0.5" />
              <div>
                <span className="text-[10px] font-bold text-red-400/90 block">
                  메모리가 가득 찼습니다 ({memories.length}/{settings.max_memories})
                </span>
                <span className="text-[9px] text-red-400/60">
                  새 메모리 추가 시 가장 오래된 메모리가 자동으로 교체됩니다
                </span>
              </div>
            </div>
          )}

          {settings && settings.enabled && memories.length < settings.max_memories && memories.length >= Math.floor(settings.max_memories * settings.compression_threshold) && (
            <div className="flex items-start gap-3 p-3 rounded-xl bg-amber-500/5 border border-amber-500/10">
              <Layers className="w-4 h-4 text-amber-400 shrink-0 mt-0.5" />
              <div>
                <span className="text-[10px] font-bold text-amber-400/90 block">
                  메모리가 거의 가득 찼습니다 ({memories.length}/{settings.max_memories})
                </span>
                <span className="text-[9px] text-amber-400/60">
                  자동 압축이 활성화되어 유사한 메모리를 병합합니다
                </span>
              </div>
            </div>
          )}

          {memories.length === 0 && (
            <div className="flex flex-col items-center justify-center h-40 text-muted-foreground/30">
              <Brain className="w-8 h-8 mb-2" />
              <span className="text-[10px] font-bold uppercase tracking-widest">No memories yet</span>
              <span className="text-[9px] text-muted-foreground/20 mt-1">Memories will be auto-extracted from chats</span>
            </div>
          )}

          {memories.map((mem) => {
            const style = CATEGORY_STYLES[mem.category];
            const isEditing = editingId === mem.id;

            return (
              <div
                key={mem.id}
                className={cn(
                  "group relative rounded-xl border transition-all duration-200",
                  "bg-foreground/[0.02] border-foreground/5 hover:bg-foreground/5 hover:border-foreground/10",
                  mem.is_pinned && "border-l-2 border-l-primary/40"
                )}
              >
                <div className="px-4 py-3">
                  {isEditing ? (
                    <div className="space-y-2" onClick={(e) => e.stopPropagation()}>
                      <Input
                        value={editContent}
                        onChange={(e) => setEditContent(e.target.value)}
                        onKeyDown={(e) => {
                          if (e.key === "Enter") handleUpdate(mem.id);
                          if (e.key === "Escape") setEditingId(null);
                        }}
                        className="h-8 text-xs border-purple-500/30 bg-background/50"
                        autoFocus
                      />
                      <div className="flex items-center gap-2">
                        <div className="flex gap-1 flex-1">
                          {CATEGORIES.map((cat) => {
                            const catStyle = CATEGORY_STYLES[cat];
                            return (
                              <button
                                key={cat}
                                onClick={() => setEditCategory(cat)}
                                className={cn(
                                  "px-2 py-0.5 rounded-full text-[9px] font-black uppercase tracking-wider border transition-all",
                                  editCategory === cat
                                    ? `${catStyle.bg} ${catStyle.text} border-current`
                                    : "bg-foreground/5 text-muted-foreground/50 border-transparent hover:bg-foreground/10"
                                )}
                              >
                                {catStyle.label}
                              </button>
                            );
                          })}
                        </div>
                        <Button
                          variant="ghost" size="icon"
                          className="h-7 w-7 text-emerald-400 hover:text-emerald-300"
                          onClick={() => handleUpdate(mem.id)}
                        >
                          <Check className="w-3.5 h-3.5" />
                        </Button>
                        <Button
                          variant="ghost" size="icon"
                          className="h-7 w-7 text-muted-foreground hover:text-foreground"
                          onClick={() => setEditingId(null)}
                        >
                          <X className="w-3.5 h-3.5" />
                        </Button>
                      </div>
                    </div>
                  ) : (
                    <>
                      <div className="flex items-start justify-between gap-2">
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-1.5 mb-1.5">
                            <span className={cn(
                              "inline-block px-2 py-0.5 rounded-full text-[8px] font-black uppercase tracking-wider border",
                              style.bg, style.text
                            )}>
                              {style.label}
                            </span>
                            <button
                              onClick={() => handleTogglePin(mem.id)}
                              className={cn(
                                "transition-all",
                                mem.is_pinned
                                  ? "text-primary opacity-100"
                                  : "text-muted-foreground/30 opacity-0 group-hover:opacity-100 hover:text-muted-foreground/70"
                              )}
                              title={mem.is_pinned ? "Unpin memory" : "Pin memory"}
                            >
                              <Pin className="w-3 h-3" />
                            </button>
                          </div>
                          <p className="text-[11px] text-foreground/80 leading-relaxed">
                            {mem.content}
                          </p>
                        </div>
                        <div
                          className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
                        >
                          <Button
                            variant="ghost" size="icon"
                            className="h-6 w-6 text-muted-foreground/50 hover:text-foreground"
                            onClick={() => {
                              setEditingId(mem.id);
                              setEditContent(mem.content);
                              setEditCategory(mem.category);
                            }}
                          >
                            <Pencil className="w-3 h-3" />
                          </Button>
                          <Button
                            variant="ghost" size="icon"
                            className="h-6 w-6 text-muted-foreground/50 hover:text-red-400"
                            onClick={() => handleDelete(mem.id)}
                          >
                            <Trash2 className="w-3 h-3" />
                          </Button>
                        </div>
                      </div>
                    </>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </SheetContent>
    </Sheet>
  );
}
