/**
 * `MemoryEditor` — a fullscreen overlay for creating or editing memory notes
 * (L14). Rendered on top of the rest of the UI (`fixed inset-0`).
 *
 * Provides:
 * - Create-mode: name (slug source) + description + type selector + content
 * - Edit-mode: slug shown read-only (identity is immutable), description + type
 *   + content editable, and a read-only list of resolved `[[wikilinks]]`.
 *
 * Pure presentation: all mutations are delegated to the callbacks supplied by
 * the parent (`MemoryPanel`). Styled with `@/shared`; no inline styles.
 */

import { useEffect, useState } from "react";

import type { MemoryIndexEntry, MemoryLink, MemoryType } from "@/domain";
import { Button, Input, cn } from "@/shared";

const MEMORY_TYPES: MemoryType[] = ["user", "feedback", "project", "reference"];

export interface MemoryEditorProps {
  /**
   * When set, the editor is in edit-mode for the given index entry; otherwise it
   * is in create-mode (all fields start empty). The slug is immutable in edit.
   */
  entry?: MemoryIndexEntry | null;
  /** Loads the full content of the entry being edited (edit-mode only). */
  loadContent?: (slug: string) => Promise<string>;
  /** Resolves the entry's `[[wikilinks]]` to existing target slugs (edit-mode only). */
  resolveLinks?: (slug: string) => Promise<MemoryLink[]>;
  /** Create-mode submit: name + description + type + content. */
  onCreate: (
    name: string,
    description: string,
    type: MemoryType,
    content: string,
  ) => Promise<void>;
  /** Edit-mode submit: description + type + content (slug stays fixed). */
  onUpdate: (
    slug: string,
    description: string,
    type: MemoryType,
    content: string,
  ) => Promise<void>;
  /** Called when the user cancels / closes the overlay. */
  onClose: () => void;
  /** Whether a save operation is in flight. */
  busy?: boolean;
}

export function MemoryEditor({
  entry,
  loadContent,
  resolveLinks,
  onCreate,
  onUpdate,
  onClose,
  busy = false,
}: MemoryEditorProps) {
  const editing = entry != null;

  const [name, setName] = useState(entry?.title ?? "");
  const [description, setDescription] = useState(entry?.hook ?? "");
  const [type, setType] = useState<MemoryType>(entry?.type ?? "project");
  const [content, setContent] = useState("");
  const [links, setLinks] = useState<MemoryLink[]>([]);

  // In edit-mode, hydrate the editable content and the resolved links lazily.
  useEffect(() => {
    if (!entry) return;
    let cancelled = false;
    void (async () => {
      try {
        if (loadContent) {
          const loaded = await loadContent(entry.slug);
          if (!cancelled) setContent(loaded);
        }
        if (resolveLinks) {
          const resolved = await resolveLinks(entry.slug);
          if (!cancelled) setLinks(resolved);
        }
      } catch {
        // Best-effort hydration: leave fields as-is on failure.
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [entry, loadContent, resolveLinks]);

  const canSave =
    description.trim().length > 0 &&
    content.trim().length > 0 &&
    !busy &&
    (editing || name.trim().length > 0);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (!canSave) return;
    if (editing) {
      await onUpdate(entry.slug, description.trim(), type, content);
    } else {
      await onCreate(name.trim(), description.trim(), type, content);
    }
  }

  const selectClass = cn(
    "h-9 w-full rounded-md bg-raised px-3 text-sm text-content",
    "border border-border outline-none transition-colors",
    "focus:border-primary disabled:cursor-not-allowed disabled:opacity-50",
  );

  return (
    <div
      className="fixed inset-0 z-50 flex flex-col bg-canvas"
      role="dialog"
      aria-modal="true"
      aria-label="memory editor"
    >
      {/* ── Header bar ── */}
      <div className="flex shrink-0 items-center justify-between border-b border-border bg-surface px-4 py-3">
        <h2 className="text-sm font-semibold text-content">
          {editing ? `Edit note — ${entry.title}` : "New note"}
        </h2>
        <Button
          type="button"
          variant="ghost"
          aria-label="close memory editor"
          onClick={onClose}
          disabled={busy}
        >
          ✕
        </Button>
      </div>

      {/* ── Form body ── */}
      <form
        onSubmit={(e) => void handleSubmit(e)}
        className="flex flex-1 flex-col gap-0 overflow-hidden"
      >
        {/* ── Meta fields ── */}
        <div className="flex shrink-0 flex-wrap items-end gap-3 border-b border-border px-4 py-3">
          {editing ? (
            <div className="flex min-w-0 flex-1 flex-col gap-1">
              <span className="text-xs font-medium text-muted">Slug</span>
              <code className="truncate rounded-md border border-border bg-raised px-3 py-2 text-sm text-muted">
                {entry.slug}
              </code>
            </div>
          ) : (
            <div className="flex min-w-0 flex-1 flex-col gap-1">
              <label htmlFor="me-name" className="text-xs font-medium text-muted">
                Name
              </label>
              <Input
                id="me-name"
                aria-label="memory name"
                placeholder="My note"
                value={name}
                onChange={(e) => setName(e.target.value)}
                disabled={busy}
                className="min-w-48"
              />
            </div>
          )}

          <div className="flex min-w-0 flex-col gap-1">
            <label htmlFor="me-type" className="text-xs font-medium text-muted">
              Type
            </label>
            <select
              id="me-type"
              aria-label="memory type"
              value={type}
              onChange={(e) => setType(e.target.value as MemoryType)}
              disabled={busy}
              className={selectClass}
            >
              {MEMORY_TYPES.map((t) => (
                <option key={t} value={t}>
                  {t}
                </option>
              ))}
            </select>
          </div>
        </div>

        {/* ── Description ── */}
        <div className="flex shrink-0 flex-col gap-1 border-b border-border px-4 py-3">
          <label htmlFor="me-description" className="text-xs font-medium text-muted">
            Description
          </label>
          <Input
            id="me-description"
            aria-label="memory description"
            placeholder="One-line hook"
            value={description}
            onChange={(e) => setDescription(e.target.value)}
            disabled={busy}
          />
        </div>

        {/* ── Content ── */}
        <div className="flex flex-1 flex-col overflow-hidden px-4 py-3">
          <label htmlFor="me-content" className="mb-1 text-xs font-medium text-muted">
            Content
          </label>
          <textarea
            id="me-content"
            aria-label="memory content"
            value={content}
            onChange={(e) => setContent(e.target.value)}
            disabled={busy}
            className={cn(
              "flex-1 w-full rounded-md bg-raised px-3 py-2 text-sm text-content font-mono",
              "border border-border outline-none transition-colors resize-none",
              "focus:border-primary placeholder:text-faint",
              "disabled:cursor-not-allowed disabled:opacity-50",
            )}
            placeholder="# Note&#10;&#10;Use [[other-slug]] to link…"
          />

          {/* ── Resolved links (edit-mode, read-only) ── */}
          {editing && (
            <div className="mt-3 shrink-0">
              <h4 className="text-xs font-semibold uppercase tracking-wide text-faint">
                Links
              </h4>
              {links.length === 0 ? (
                <p className="mt-1 text-sm text-muted">No resolved links.</p>
              ) : (
                <ul className="mt-1 flex flex-wrap gap-1.5">
                  {links.map((slug) => (
                    <li
                      key={slug}
                      className="rounded-md border border-border bg-raised px-2 py-0.5 text-xs text-muted"
                    >
                      {slug}
                    </li>
                  ))}
                </ul>
              )}
            </div>
          )}
        </div>

        {/* ── Footer ── */}
        <div className="flex shrink-0 items-center justify-end gap-2 border-t border-border px-4 py-3">
          <Button type="button" variant="ghost" onClick={onClose} disabled={busy}>
            Cancel
          </Button>
          <Button
            type="submit"
            variant="primary"
            aria-label="Save note"
            disabled={!canSave}
            loading={busy}
          >
            Save
          </Button>
        </div>
      </form>
    </div>
  );
}
