'use client'

import * as React from 'react'
import type { Editor } from '@tiptap/core'
import { getSelectedContentEditorMath } from '@admin/utils/editor/get-selected-content-editor-math'
import { removeSelectedContentEditorMath } from '@admin/utils/editor/remove-selected-content-editor-math'
import { updateSelectedContentEditorMath } from '@admin/utils/editor/update-selected-content-editor-math'
import { cn } from '@admin/utils/shared/cn'
import { BubbleMenu } from '@tiptap/react/menus'
import { MathEditorControls } from './math-editor-controls'

export function MathBubbleMenu({ editor }: { editor: Editor }) {
  const [selectedMath, setSelectedMath] = React.useState(() => getSelectedContentEditorMath(editor))

  const syncSelectedMath = React.useCallback(() => {
    setSelectedMath(getSelectedContentEditorMath(editor))
  }, [editor])

  React.useEffect(() => {
    editor.on('selectionUpdate', syncSelectedMath)
    editor.on('transaction', syncSelectedMath)
    syncSelectedMath()

    return () => {
      editor.off('selectionUpdate', syncSelectedMath)
      editor.off('transaction', syncSelectedMath)
    }
  }, [editor, syncSelectedMath])

  const applyMath = React.useCallback(
    (value: string) => {
      const didApply = updateSelectedContentEditorMath(editor, value, selectedMath)
      syncSelectedMath()
      return didApply
    },
    [editor, selectedMath, syncSelectedMath]
  )

  const removeMath = React.useCallback(() => {
    const didRemove = removeSelectedContentEditorMath(editor, selectedMath)
    syncSelectedMath()
    return didRemove
  }, [editor, selectedMath, syncSelectedMath])

  return (
    <BubbleMenu
      editor={editor}
      pluginKey="mathBubbleMenu"
      updateDelay={0}
      shouldShow={({ editor: currentEditor }) =>
        currentEditor.isEditable && Boolean(getSelectedContentEditorMath(currentEditor))
      }
      options={{
        flip: { padding: 8 },
        offset: 8,
        placement: 'top',
        shift: { padding: 8 }
      }}
    >
      <div
        role="toolbar"
        aria-label="Math formatting toolbar"
        className={cn(
          'flex items-center gap-1 overflow-x-auto rounded-sm border border-border bg-popover p-0 text-popover-foreground shadow-menu [scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
          'relative z-50'
        )}
      >
        <MathEditorControls
          key={`${selectedMath?.kind ?? 'math'}:${selectedMath?.pos ?? 0}:${selectedMath?.raw ?? ''}`}
          initialValue={selectedMath?.value ?? ''}
          disabled={!editor.isEditable}
          onApply={applyMath}
          onRemove={removeMath}
        />
      </div>
    </BubbleMenu>
  )
}
