import { useEffect, useRef, useCallback } from "react";
import { useEditor, EditorContent } from "@tiptap/react";
import type { Editor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Placeholder from "@tiptap/extension-placeholder";
import Link from "@tiptap/extension-link";
import { Table, TableRow, TableCell, TableHeader } from "@tiptap/extension-table";
import { SlashCommands } from "./SlashCommands";
import { PageLinkExtension } from "./PageLinkExtension";
import { BlockSelectionExtension } from "./BlockSelectionExtension";
import { createPageLinkDeletionDetector } from "./PageLinkDeletionDetector";
import { BlockDragHandle } from "./BlockDragHandle";

interface TiptapEditorProps {
  content: string | null;
  onUpdate: (json: string) => void;
  entityId: string;
  enablePageLinks?: boolean;
  onPageLinkClick?: (pageId: string) => void;
  onSubpageCreate?: (
    editor: Editor,
  ) => void;
  onPageLinkDeleted?: (pageId: string, redo: () => void) => void;
}

export function TiptapEditor({
  content,
  onUpdate,
  entityId,
  enablePageLinks = true,
  onPageLinkClick,
  onSubpageCreate,
  onPageLinkDeleted,
}: TiptapEditorProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const onPageLinkDeletedRef = useRef(onPageLinkDeleted);
  onPageLinkDeletedRef.current = onPageLinkDeleted;

  const pageLinkDeletionDetector = createPageLinkDeletionDetector(onPageLinkDeletedRef);

  const baseExtensions = [
    StarterKit,
    Table.configure({ resizable: true, cellMinWidth: 50 }),
    TableRow,
    TableCell,
    TableHeader,
    Placeholder.configure({
      includeChildren: true,
      placeholder: ({ node }) => {
        if (node.type.name === 'heading') {
          return `Heading ${node.attrs.level}`;
        }
        return "Type '/' for commands...";
      },
    }),
    Link.configure({
      openOnClick: false,
    }),
    SlashCommands,
    BlockSelectionExtension,
  ];

  const extensions = enablePageLinks
    ? [...baseExtensions, PageLinkExtension, pageLinkDeletionDetector]
    : baseExtensions;

  const editor = useEditor(
    {
      extensions,
      content: content ? JSON.parse(content) : undefined,
      onUpdate: ({ editor: e }) => {
        onUpdate(JSON.stringify(e.getJSON()));
      },
      editorProps: {
        attributes: {
          class:
            "prose prose-sm prose-p:my-1 prose-headings:mb-1 prose-headings:mt-3 prose-ul:my-1 prose-ol:my-1 prose-li:my-0.5 prose-blockquote:my-1 prose-pre:my-1 prose-hr:my-2 dark:prose-invert max-w-none focus:outline-none min-h-[400px] pl-11 pr-4 py-1",
        },
      },
    },
    [entityId],
  );

  // Wire the onSubpageCreate callback into editor storage
  useEffect(() => {
    if (editor) {
      if (onSubpageCreate) {
        editor.storage.slashCommands.onSubpageCreate = (ed: Editor) => {
          onSubpageCreate(ed);
        };
      }
      editor.storage.slashCommands.hideSubpage = !enablePageLinks;
    }
  }, [editor, onSubpageCreate, enablePageLinks]);

  // Handle page link clicks via custom event
  const handlePageLinkClick = useCallback(
    (e: Event) => {
      const detail = (e as CustomEvent).detail;
      if (detail?.pageId && onPageLinkClick) {
        onPageLinkClick(detail.pageId);
      }
    },
    [onPageLinkClick],
  );

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    el.addEventListener("page-link-click", handlePageLinkClick);
    return () =>
      el.removeEventListener("page-link-click", handlePageLinkClick);
  }, [handlePageLinkClick]);

  return (
    <div ref={containerRef}>
      <BlockDragHandle editor={editor}>
        <EditorContent editor={editor} />
      </BlockDragHandle>
    </div>
  );
}
