// TipTap-backed narrative editor.
// Renders the same prose surface as the static port, but typing actually works
// and chips can be inserted via the slash menu (`/block`, `/property`, etc.).

"use client";

import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import { useEffect, useMemo } from "react";
import { ChipNode } from "./ChipNode";
import { SlashExtension } from "./SlashExtension";
import { ChipFocusContext } from "./FocusContext";
import { fixtureToDoc } from "./fixtureToDoc";
import type { Density } from "../socrates/SocratesDock";
import type { FixtureData } from "../../lib/fixtures/aristotle";
import type { MarkupStyle } from "./Chip";

interface TextCanvasProps {
  data: FixtureData;
  density: Density;
  markupStyle: MarkupStyle;
  focusBlockId: string | null;
  setFocusBlockId: (id: string | null) => void;
}

export function TextCanvas({ data, density, markupStyle, focusBlockId, setFocusBlockId }: TextCanvasProps) {
  const padY = density === "compact" ? 10 : 18;
  const padX = density === "compact" ? 22 : 36;
  const focusValue = useMemo(
    () => ({ focusBlockId, setFocusBlockId }),
    [focusBlockId, setFocusBlockId]
  );

  const editor = useEditor({
    immediatelyRender: false,
    extensions: [
      StarterKit.configure({
        heading: { levels: [1, 2] },
        // Drop features we don't need yet
        codeBlock: false,
        blockquote: false,
        horizontalRule: false,
        bulletList: false,
        orderedList: false,
        listItem: false,
        strike: false,
        code: false,
        link: false,
      }),
      ChipNode,
      SlashExtension,
    ],
    content: fixtureToDoc(data),
    editorProps: {
      attributes: {
        class: "text-canvas tiptap",
        style: `padding: ${padY}px ${padX}px;`,
      },
    },
  });

  // Push the markup style into the editor so the ChipView NodeView can read it.
  useEffect(() => {
    if (!editor) return;
    (editor.storage as Record<string, unknown>).markupStyle = markupStyle;
    // Force a re-render of all chip node views so they pick up the new style.
    editor.view.dispatch(editor.state.tr.setMeta("force-update", true));
  }, [editor, markupStyle]);

  if (!editor) {
    return (
      <div className="text-canvas" style={{ padding: `${padY}px ${padX}px` }}>
        <div style={{ color: "var(--muted)", fontFamily: "var(--font-mono)", fontSize: 12 }}>
          loading editor…
        </div>
      </div>
    );
  }

  return (
    <ChipFocusContext.Provider value={focusValue}>
      <EditorContent editor={editor} />
      <div className="margin-note" style={{ margin: `0 ${padX}px ${padY}px ${padX}px`, maxWidth: 720 }}>
        <span className="margin-note-glyph">Σ</span>
        <span>
          <span className="margin-note-who">Socrates · margin</span>
          <span className="margin-note-text">
            &ldquo;Refuses to produce solutions&rdquo; is a strong constraint. Have you decided what counts as a &ldquo;solution&rdquo; vs. a &ldquo;scaffold&rdquo;? This boundary will determine whether the refusal policy is enforceable.
          </span>
        </span>
      </div>
    </ChipFocusContext.Provider>
  );
}
