"use client";

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { MEMORY_CATEGORIES, type MemoryCategory } from "@adventureos/shared";

type Memory = {
  id: string;
  category: string;
  title: string;
  content: string;
  sourceType: string;
  enabled: boolean;
  userVerified: boolean;
};

type Suggestion = {
  id: string;
  category: string;
  title: string;
  content: string;
  confidence: string;
  sourceType: string;
};

export function AiMemoryPanel() {
  const qc = useQueryClient();
  const [tab, setTab] = useState<"memories" | "suggestions" | "summary" | "learning">("memories");
  const [filter, setFilter] = useState("");
  const [category, setCategory] = useState("");
  const [newMem, setNewMem] = useState({ category: "likes" as MemoryCategory, title: "", content: "" });

  const { data } = useQuery({
    queryKey: ["ai-memory", filter, category],
    queryFn: async () => {
      const params = new URLSearchParams();
      if (filter) params.set("q", filter);
      if (category) params.set("category", category);
      const res = await fetch(`/api/ai/memory?${params}`);
      return res.json();
    },
  });

  const { data: learningData } = useQuery({
    queryKey: ["ai-memory-learning"],
    queryFn: async () => {
      const res = await fetch("/api/ai/memory/learning");
      return res.json();
    },
  });

  const { data: suggestionsData } = useQuery({
    queryKey: ["ai-memory-suggestions"],
    queryFn: async () => {
      const res = await fetch("/api/ai/memory/suggestions");
      return res.json();
    },
  });

  const createMem = useMutation({
    mutationFn: async () => {
      const res = await fetch("/api/ai/memory", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(newMem),
      });
      return res.json();
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ["ai-memory"] });
      setNewMem({ category: "likes", title: "", content: "" });
    },
  });

  const saveSummary = useMutation({
    mutationFn: async (summary: string) => {
      const res = await fetch("/api/ai/memory/summary", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ summary }),
      });
      return res.json();
    },
    onSuccess: () => qc.invalidateQueries({ queryKey: ["ai-memory"] }),
  });

  const saveLearning = useMutation({
    mutationFn: async (body: Record<string, unknown>) => {
      const res = await fetch("/api/ai/memory/learning", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      return res.json();
    },
    onSuccess: () => qc.invalidateQueries({ queryKey: ["ai-memory-learning"] }),
  });

  const memories: Memory[] = data?.memories ?? [];
  const summary = data?.summary?.summary ?? "";
  const suggestions: Suggestion[] = suggestionsData?.suggestions ?? [];
  const learning = learningData ?? {};

  return (
    <div className="space-y-4">
      <p className="text-sm text-[var(--warm-grey)]">
        What the AI knows about you — fully editable. Raw logs and reflections stay separate.
      </p>

      <div className="flex flex-wrap gap-1">
        {(["memories", "suggestions", "summary", "learning"] as const).map((t) => (
          <button
            key={t}
            type="button"
            className={`retro-btn text-xs ${tab === t ? "retro-btn-primary" : ""}`}
            onClick={() => setTab(t)}
          >
            {t === "suggestions" ? `Suggestions (${suggestions.length})` : t.charAt(0).toUpperCase() + t.slice(1)}
          </button>
        ))}
      </div>

      {tab === "memories" && (
        <>
          <div className="flex gap-2 flex-wrap">
            <input
              className="retro-window-inset p-1 text-sm flex-1 min-w-[120px]"
              placeholder="Search memories..."
              value={filter}
              onChange={(e) => setFilter(e.target.value)}
            />
            <select
              className="retro-window-inset text-sm p-1"
              value={category}
              onChange={(e) => setCategory(e.target.value)}
            >
              <option value="">All categories</option>
              {Object.entries(MEMORY_CATEGORIES).map(([k, v]) => (
                <option key={k} value={k}>{v}</option>
              ))}
            </select>
          </div>

          <div className="retro-window p-3 space-y-2">
            <p className="text-xs font-bold">Add memory manually</p>
            <select
              className="retro-window-inset text-sm p-1 w-full"
              value={newMem.category}
              onChange={(e) => setNewMem({ ...newMem, category: e.target.value as MemoryCategory })}
            >
              {Object.entries(MEMORY_CATEGORIES).map(([k, v]) => (
                <option key={k} value={k}>{v}</option>
              ))}
            </select>
            <input
              className="retro-window-inset p-1 text-sm w-full"
              placeholder="Title"
              value={newMem.title}
              onChange={(e) => setNewMem({ ...newMem, title: e.target.value })}
            />
            <textarea
              className="retro-window-inset p-1 text-sm w-full"
              placeholder="What should the AI remember?"
              rows={2}
              value={newMem.content}
              onChange={(e) => setNewMem({ ...newMem, content: e.target.value })}
            />
            <button
              type="button"
              className="retro-btn retro-btn-primary text-xs"
              disabled={!newMem.title.trim() || !newMem.content.trim()}
              onClick={() => createMem.mutate()}
            >
              Add memory
            </button>
          </div>

          <div className="space-y-2 max-h-96 overflow-y-auto">
            {memories.map((m) => (
              <MemoryRow key={m.id} memory={m} onChange={() => qc.invalidateQueries({ queryKey: ["ai-memory"] })} />
            ))}
            {memories.length === 0 && (
              <p className="text-sm italic text-[var(--warm-grey)]">No memories yet. Add one above.</p>
            )}
          </div>

          <div className="flex gap-2">
            <a href="/api/ai/memory/summary" className="retro-btn text-xs" download>
              Export memories
            </a>
            <button
              type="button"
              className="retro-btn text-xs text-[var(--muted-rose)]"
              onClick={async () => {
                if (!confirm("Archive all memories? This cannot be undone easily.")) return;
                await fetch("/api/ai/memory/reset", {
                  method: "POST",
                  headers: { "Content-Type": "application/json" },
                  body: JSON.stringify({ confirm: true }),
                });
                qc.invalidateQueries({ queryKey: ["ai-memory"] });
              }}
            >
              Reset all memories
            </button>
          </div>
        </>
      )}

      {tab === "suggestions" && (
        <div className="space-y-2">
          {suggestions.length === 0 && (
            <p className="text-sm italic">No pending suggestions. Enable learning to receive them.</p>
          )}
          {suggestions.map((s) => (
            <SuggestionRow key={s.id} suggestion={s} onChange={() => {
              qc.invalidateQueries({ queryKey: ["ai-memory-suggestions"] });
              qc.invalidateQueries({ queryKey: ["ai-memory"] });
            }} />
          ))}
        </div>
      )}

      {tab === "summary" && (
        <div className="space-y-2">
          <p className="text-xs text-[var(--warm-grey)]">
            AI-generated profile summary (editable). Used as compact context for the mentor.
          </p>
          <textarea
            className="retro-window-inset p-2 text-sm w-full"
            rows={6}
            value={summary}
            onChange={(e) => saveSummary.mutate(e.target.value)}
          />
          <button
            type="button"
            className="retro-btn text-xs"
            onClick={async () => {
              const res = await fetch("/api/ai/memory/summary/rebuild", { method: "POST" });
              if (res.ok) qc.invalidateQueries({ queryKey: ["ai-memory"] });
            }}
          >
            Rebuild from memories
          </button>
        </div>
      )}

      {tab === "learning" && (
        <div className="space-y-3">
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={learning.learningEnabled ?? false}
              onChange={(e) => saveLearning.mutate({ learningEnabled: e.target.checked })}
            />
            Enable memory learning (opt-in)
          </label>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={learning.requireApproval ?? true}
              onChange={(e) => saveLearning.mutate({ requireApproval: e.target.checked })}
            />
            Require approval before saving
          </label>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={learning.suggestAfterReflection ?? true}
              onChange={(e) => saveLearning.mutate({ suggestAfterReflection: e.target.checked })}
            />
            Suggest after reflections
          </label>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={learning.allowSensitiveCategories ?? false}
              onChange={(e) => saveLearning.mutate({ allowSensitiveCategories: e.target.checked })}
            />
            Allow learning sensitive categories
          </label>
        </div>
      )}
    </div>
  );
}

function MemoryRow({ memory, onChange }: { memory: Memory; onChange: () => void }) {
  const toggle = async () => {
    await fetch(`/api/ai/memory/${memory.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ enabled: !memory.enabled }),
    });
    onChange();
  };

  const archive = async () => {
    await fetch(`/api/ai/memory/${memory.id}`, { method: "DELETE" });
    onChange();
  };

  return (
    <div className={`retro-window p-2 text-sm ${!memory.enabled ? "opacity-50" : ""}`}>
      <div className="flex justify-between gap-2">
        <span className="font-bold">{memory.title}</span>
        <span className="text-xs text-[var(--warm-grey)]">
          {MEMORY_CATEGORIES[memory.category as MemoryCategory] ?? memory.category}
        </span>
      </div>
      <p className="text-xs mt-1">{memory.content}</p>
      <p className="text-[10px] text-[var(--warm-grey)] mt-1">Source: {memory.sourceType}</p>
      <div className="flex gap-2 mt-2">
        <button type="button" className="retro-btn text-xs" onClick={toggle}>
          {memory.enabled ? "Disable" : "Enable"}
        </button>
        <button type="button" className="retro-btn text-xs" onClick={archive}>Archive</button>
      </div>
    </div>
  );
}

function SuggestionRow({ suggestion, onChange }: { suggestion: Suggestion; onChange: () => void }) {
  const [editing, setEditing] = useState(false);
  const [title, setTitle] = useState(suggestion.title);
  const [content, setContent] = useState(suggestion.content);
  const [category, setCategory] = useState(suggestion.category);

  return (
    <div className="retro-window p-2 text-sm border-l-4 border-[var(--xp-blue)]">
      {editing ? (
        <div className="space-y-2">
          <input
            className="retro-window-inset w-full p-1 text-xs"
            value={title}
            onChange={(e) => setTitle(e.target.value)}
          />
          <select
            className="retro-window-inset w-full p-1 text-xs"
            value={category}
            onChange={(e) => setCategory(e.target.value)}
          >
            {Object.entries(MEMORY_CATEGORIES).map(([key, label]) => (
              <option key={key} value={key}>{label}</option>
            ))}
          </select>
          <textarea
            className="retro-window-inset w-full p-1 text-xs min-h-20"
            value={content}
            onChange={(e) => setContent(e.target.value)}
          />
        </div>
      ) : (
        <>
          <p className="font-bold">{suggestion.title}</p>
          <p className="text-xs mt-1">{suggestion.content}</p>
          <p className="text-[10px] text-[var(--warm-grey)]">
            {MEMORY_CATEGORIES[suggestion.category as MemoryCategory]} · confidence {suggestion.confidence}
          </p>
        </>
      )}
      <div className="flex gap-2 mt-2">
        <button
          type="button"
          className="retro-btn retro-btn-primary text-xs"
          onClick={async () => {
            await fetch(`/api/ai/memory/suggestions/${suggestion.id}/accept`, {
              method: "POST",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify(editing ? { title, content, category } : {}),
            });
            onChange();
          }}
          disabled={!title.trim() || !content.trim()}
        >
          Accept
        </button>
        <button
          type="button"
          className="retro-btn text-xs"
          onClick={() => setEditing((value) => !value)}
        >
          {editing ? "Cancel edit" : "Edit"}
        </button>
        <button
          type="button"
          className="retro-btn text-xs"
          onClick={async () => {
            await fetch(`/api/ai/memory/suggestions/${suggestion.id}/reject`, { method: "POST" });
            onChange();
          }}
        >
          Reject
        </button>
        <button
          type="button"
          className="retro-btn text-xs"
          onClick={async () => {
            await fetch(`/api/ai/memory/suggestions/${suggestion.id}/ignore`, { method: "POST" });
            onChange();
          }}
        >
          Ignore
        </button>
      </div>
    </div>
  );
}
