'use client';

import { useCallback, useMemo, useRef } from 'react';

import {
  LazyMarkdownEditor as MarkdownEditor,
  type MarkdownEditorHandle,
  type MentionConfig,
} from '@djangocfg/ui-tools/markdown-editor';

import { useRegisterComposer } from '../hooks/useAutoFocusOnStreamEnd';
import type { ComposerSize, ComposerTextareaProps } from './types';

/** Single-row baseline height per composer size (px). */
const MIN_HEIGHT: Record<ComposerSize, number> = {
  sm: 20,
  md: 24,
  lg: 28,
};

export interface ComposerRichTextareaProps extends ComposerTextareaProps {
  /** `@`-mention autocomplete config. Omit for a plain rich textarea. */
  mentions?: MentionConfig;
}

/**
 * Drop-in TipTap-backed textarea for the composer's Tier B `Textarea`
 * slot. Pre-wired with chat defaults — `unstyled` (the composer surface
 * draws the frame), no toolbar, size-matched single-row height, and
 * Enter-to-send. The host passes only `mentions` if it needs `@`
 * autocomplete; everything else flows from `ComposerTextareaProps`.
 *
 * @example
 * <Composer
 *   slots={{ Textarea: (p) => <ComposerRichTextarea {...p} mentions={cfg} /> }}
 * />
 */
export function ComposerRichTextarea({
  composer,
  placeholder,
  disabled,
  size,
  className,
  mentions,
}: ComposerRichTextareaProps) {
  // Tiptap captures the mentions object once on first render — keep its
  // identity stable so the suggestion plugin stays wired.
  const stableMentions = useMemo(() => mentions, [mentions]);

  // The TipTap editor has no `<textarea>`, so the composer's default
  // `focus` handle (which targets `textareaRef`) is a no-op here.
  // Register the editor's real imperative handle with the chat context
  // so `useAutoFocusOnStreamEnd` (refocus after the assistant reply)
  // and the voice slot actually drive *this* editor.
  const editorRef = useRef<MarkdownEditorHandle>(null);
  const focus = useCallback(() => editorRef.current?.focus(), []);
  const moveCursorToEnd = useCallback(
    () => editorRef.current?.moveCursorToEnd(),
    [],
  );
  const getValue = useCallback(() => composer.value, [composer.value]);
  useRegisterComposer({
    focus,
    moveCursorToEnd,
    getValue,
    setValue: composer.setValue,
  });

  return (
    <div className={className ?? 'min-w-0 flex-1'}>
      <MarkdownEditor
        ref={editorRef}
        value={composer.value}
        onChange={composer.setValue}
        mentions={stableMentions}
        placeholder={placeholder}
        minHeight={MIN_HEIGHT[size]}
        showToolbar={false}
        unstyled
        disabled={disabled}
        onSubmit={() => {
          if (composer.canSubmit) void composer.submit();
          return true;
        }}
      />
    </div>
  );
}
