"use client"

import { useEffect, useRef } from "react"
import { useEditor, EditorContent, type Editor } from "@tiptap/react"
import {
  buildRegionEditorExtensions,
  RICHTEXT_REGION_EDITOR_CLASS,
} from "@/lib/drive/richtext-extensions"
import { cn } from "@/lib/utils"

function regionEditorProseStyle(maxHeightPx?: number, minHeightPx?: number): string | undefined {
  const parts: string[] = []
  if (minHeightPx != null) parts.push(`min-height:${minHeightPx}px`)
  if (maxHeightPx != null) {
    parts.push(`max-height:${maxHeightPx}px`, "overflow-y:auto")
  }
  return parts.length > 0 ? parts.join(";") : undefined
}

export function DocsRegionEditor({
  content,
  editable,
  placeholder,
  className,
  maxHeightPx,
  minHeightPx,
  onUpdate,
  onBlur,
  onEditorReady,
  onContentHeightChange,
  autoFocus,
}: {
  content: Record<string, unknown> | undefined
  editable: boolean
  placeholder?: string
  className?: string
  /** When set, content scrolls inside. Omit to grow with content. */
  maxHeightPx?: number
  /** Minimum editable band height (header/footer margin zone). */
  minHeightPx?: number
  onUpdate?: (json: Record<string, unknown>) => void
  onBlur?: () => void
  onEditorReady?: (editor: Editor | null) => void
  onContentHeightChange?: (height: number) => void
  autoFocus?: boolean
}) {
  const syncingRef = useRef(false)
  const rootRef = useRef<HTMLDivElement>(null)
  const proseStyle = regionEditorProseStyle(maxHeightPx, minHeightPx)

  const editor = useEditor({
    immediatelyRender: false,
    editable,
    extensions: buildRegionEditorExtensions(placeholder),
    content: content ?? { type: "doc", content: [{ type: "paragraph" }] },
    editorProps: {
      attributes: {
        class: RICHTEXT_REGION_EDITOR_CLASS,
        ...(proseStyle ? { style: proseStyle } : {}),
      },
    },
    onUpdate: ({ editor: ed }) => {
      if (syncingRef.current) return
      onUpdate?.(ed.getJSON() as Record<string, unknown>)
    },
    onBlur: () => onBlur?.(),
  })

  useEffect(() => {
    onEditorReady?.(editor)
    return () => onEditorReady?.(null)
  }, [editor, onEditorReady])

  useEffect(() => {
    if (!editor || !content) return
    syncingRef.current = true
    editor.commands.setContent(content, { emitUpdate: false })
    syncingRef.current = false
  }, [content, editor])

  useEffect(() => {
    editor?.setEditable(editable)
    if (editable && autoFocus) {
      requestAnimationFrame(() => editor?.commands.focus("end"))
    }
  }, [autoFocus, editable, editor])

  useEffect(() => {
    if (!editor) return
    const style = regionEditorProseStyle(maxHeightPx, minHeightPx)
    editor.setOptions({
      editorProps: {
        attributes: {
          class: RICHTEXT_REGION_EDITOR_CLASS,
          ...(style ? { style } : {}),
        },
      },
    })
  }, [editor, maxHeightPx, minHeightPx])

  useEffect(() => {
    const root = rootRef.current
    if (!root || !onContentHeightChange) return
    const prose = root.querySelector(".ProseMirror") as HTMLElement | null
    if (!prose) return

    const report = () => {
      requestAnimationFrame(() => onContentHeightChange(prose.offsetHeight))
    }
    report()
    const ro = new ResizeObserver(report)
    ro.observe(prose)
    return () => ro.disconnect()
  }, [editor, onContentHeightChange])

  if (!editor) return null

  return (
    <div
      ref={rootRef}
      className={cn("docs-region-editor-root", maxHeightPx == null && "docs-region-editor-root--grow")}
      style={minHeightPx != null ? { minHeight: minHeightPx } : undefined}
    >
      <EditorContent
        editor={editor}
        className={cn("docs-region-editor", maxHeightPx == null ? "docs-region-editor--grow" : "h-full", className)}
        style={
          maxHeightPx != null
            ? { height: maxHeightPx, maxHeight: maxHeightPx }
            : undefined
        }
      />
    </div>
  )
}
