'use client';

import * as React from 'react';
import { clsx } from 'clsx';
import { EditorContent, useEditor } from '@tiptap/react';
import type { AnyExtension, JSONContent } from '@tiptap/core';

import { buildExtensions } from './extensions.js';
import { SlashCommands } from './slashMenu.js';
import { createMention, type UserSearchFn } from './mention.js';
import { Toolbar } from './Toolbar.js';

export interface RichTextEditorProps {
  /** Initial document — Tiptap JSON or an HTML string. */
  content?: JSONContent | string;
  /** Called with the latest JSON document on every change. */
  onChange?: (doc: JSONContent) => void;
  /** Placeholder shown when empty. */
  placeholder?: string;
  /** Enable the `/` slash command menu (default true). */
  enableSlashMenu?: boolean;
  /** Provide to enable `@`-mentions backed by this people search. */
  mentionSearch?: UserSearchFn;
  /** Read-only mode. */
  editable?: boolean;
  className?: string;
  ariaLabel?: string;
}

/**
 * Full editor surface: token-themed toolbar + Tiptap editing area, with an
 * optional slash menu and async mentions. SSR-safe (`immediatelyRender:
 * false`) so it hydrates cleanly under Next.
 */
export function RichTextEditor({
  content,
  onChange,
  placeholder,
  enableSlashMenu = true,
  mentionSearch,
  editable = true,
  className,
  ariaLabel = 'Rich text editor',
}: RichTextEditorProps) {
  const extra = React.useMemo<AnyExtension[]>(() => {
    const list: AnyExtension[] = [];
    if (enableSlashMenu) list.push(SlashCommands);
    if (mentionSearch) list.push(createMention(mentionSearch));
    // Extensions are fixed for a mount; deliberately not reactive.
    return list;
  }, []);

  const editor = useEditor({
    immediatelyRender: false,
    editable,
    extensions: buildExtensions({ placeholder, extra }),
    content,
    editorProps: {
      attributes: {
        role: 'textbox',
        'aria-multiline': 'true',
        'aria-label': ariaLabel,
        class: 'bl-rich-text-content min-h-40 p-3 outline-none',
      },
    },
    onUpdate: ({ editor: e }) => onChange?.(e.getJSON()),
  });

  React.useEffect(() => {
    editor?.setEditable(editable);
  }, [editor, editable]);

  return (
    <div
      className={clsx(
        'overflow-hidden rounded-xl border border-[var(--bl-border,rgba(0,0,0,0.12))] bg-[var(--bl-surface-card,#fff)]',
        className
      )}
    >
      {editable && <Toolbar editor={editor} />}
      <EditorContent editor={editor} />
    </div>
  );
}
