/**
 * `MemoryPanel` — feature component for project memory management (L14).
 *
 * Pure presentation: all behaviour comes from {@link useMemory}. Styled with
 * `@/shared` design system tokens; no inline styles.
 *
 * Provides:
 * - The recall-oriented memory index (title + hook + type badge)
 * - A "New note" button that opens {@link MemoryEditor} in create-mode
 * - Per-entry "Edit" (opens the editor in edit-mode) and "Delete"
 *
 * The editor needs the full note content (the index only carries the hook), so
 * it loads it lazily through the memory gateway's `getMemory`.
 */

import { useCallback, useState } from "react";

import type { MemoryIndexEntry } from "@/domain";
import { Button, Panel, Spinner } from "@/shared";
import { useGateways } from "@/app/di";
import { useEmbedder } from "@/features/embedder";
import { MemoryEditor } from "./MemoryEditor";
import { useMemory } from "./useMemory";

export interface MemoryPanelProps {
  /** The project whose memory notes to manage. */
  projectId: string;
}

/** Editor open-state: "create" or edit-mode for a specific index entry. */
type EditorState = { mode: "create" } | { mode: "edit"; entry: MemoryIndexEntry };

export function MemoryPanel({ projectId }: MemoryPanelProps) {
  const vm = useMemory(projectId);
  const embedderVm = useEmbedder();
  const { memory } = useGateways();

  const [editorState, setEditorState] = useState<EditorState | null>(null);
  const [editorBusy, setEditorBusy] = useState(false);

  const loadContent = useCallback(
    async (slug: string) => (await memory.getMemory(projectId, slug)).content,
    [memory, projectId],
  );

  async function handleCreate(
    name: string,
    description: string,
    type: MemoryIndexEntry["type"],
    content: string,
  ) {
    setEditorBusy(true);
    try {
      await vm.createMemory({ name, description, type, content });
      setEditorState(null);
    } finally {
      setEditorBusy(false);
    }
  }

  async function handleUpdate(
    slug: string,
    description: string,
    type: MemoryIndexEntry["type"],
    content: string,
  ) {
    setEditorBusy(true);
    try {
      await vm.updateMemory(slug, description, type, content);
      setEditorState(null);
    } finally {
      setEditorBusy(false);
    }
  }

  return (
    <>
      {/* ── Fullscreen memory editor overlay ── */}
      {editorState !== null && (
        <MemoryEditor
          entry={editorState.mode === "edit" ? editorState.entry : null}
          loadContent={loadContent}
          resolveLinks={vm.resolveLinks}
          onCreate={handleCreate}
          onUpdate={handleUpdate}
          onClose={() => setEditorState(null)}
          busy={editorBusy}
        />
      )}

      <Panel title="Memory" className="flex flex-col gap-0">
        {/* ── Active recall tier (read-only transparency) ── */}
        <p
          className="border-b border-border px-4 py-2 text-xs text-faint"
          data-testid="memory-tier"
        >
          Tier:{" "}
          {embedderVm.active ? (
            <span className="text-content">
              Vector — {embedderVm.active.strategy}
              {embedderVm.active.model ? ` ${embedderVm.active.model}` : ""}
            </span>
          ) : (
            <span className="text-content">Naïve (None)</span>
          )}
        </p>

        {vm.error && (
          <p
            role="alert"
            className="mx-4 mt-3 rounded-md border border-danger/40 bg-danger/10 px-3 py-2 text-sm text-danger"
          >
            {vm.error}
          </p>
        )}

        {/* ── Create button ── */}
        <div className="flex items-center justify-between border-b border-border px-4 py-3">
          <h4 className="text-xs font-semibold uppercase tracking-wide text-faint">
            Notes
          </h4>
          <div className="flex items-center gap-2">
            {vm.busy && <Spinner size={14} />}
            <Button
              type="button"
              variant="primary"
              aria-label="create memory"
              disabled={vm.busy}
              onClick={() => setEditorState({ mode: "create" })}
            >
              New note
            </Button>
          </div>
        </div>

        {/* ── Index list ── */}
        <div className="p-4">
          {vm.entries.length === 0 ? (
            <p className="text-sm text-muted">No memory notes yet.</p>
          ) : (
            <ul className="flex flex-col divide-y divide-border">
              {vm.entries.map((e) => (
                <li
                  key={e.slug}
                  className="flex items-center justify-between gap-3 py-3 first:pt-0 last:pb-0"
                >
                  <span className="flex min-w-0 flex-col gap-0.5">
                    <span className="flex items-center gap-2">
                      <span className="min-w-0 truncate font-medium text-content">
                        {e.title}
                      </span>
                      <span className="shrink-0 rounded border border-border bg-raised px-1.5 py-0.5 text-[10px] uppercase tracking-wide text-muted">
                        {e.type}
                      </span>
                    </span>
                    <span className="truncate text-xs text-muted">{e.hook}</span>
                  </span>
                  <div className="flex shrink-0 items-center gap-1.5">
                    <Button
                      size="sm"
                      variant="ghost"
                      aria-label={`edit memory ${e.title}`}
                      disabled={vm.busy}
                      onClick={() => setEditorState({ mode: "edit", entry: e })}
                    >
                      Edit
                    </Button>
                    <Button
                      size="sm"
                      variant="ghost"
                      aria-label={`delete memory ${e.title}`}
                      disabled={vm.busy}
                      onClick={() => void vm.deleteMemory(e.slug)}
                      className="text-danger hover:text-danger"
                    >
                      Delete
                    </Button>
                  </div>
                </li>
              ))}
            </ul>
          )}
        </div>
      </Panel>
    </>
  );
}
