"use client"

import { useEffect, useRef, useState, type ReactNode } from "react"
import type { Editor } from "@tiptap/react"
import { DocsPageView } from "@/components/drive/richtext/docs-page-view"
import {
  DocsRulerToolbarRow,
  DocsRulersLeftRail,
} from "@/components/drive/richtext/docs-rulers-chrome"
import type { DocPageLayout } from "@/lib/drive/doc-page-setup"
import { DOCS_VERTICAL_RULER_WIDTH_PX } from "@/lib/drive/docs-page-layout-constants"
import { docsZoomToScale } from "@/lib/drive/docs-ruler-scale"
import { useDocsRulerSync } from "@/lib/drive/use-docs-ruler-sync"
import { useDocsRulerMarginDrag } from "@/components/drive/richtext/use-docs-ruler-margin-drag"
import { DocsRulerMarginDragTooltip } from "@/components/drive/richtext/docs-ruler-markers"
import { DocsGraphicFloatingToolbar } from "@/components/drive/richtext/docs-graphic-floating-toolbar"
import { DocsTableFloatingToolbar } from "@/components/drive/richtext/docs-table-floating-toolbar"
import {
  DOCS_GRAPHIC_DRAW_EVENT,
  DocsGraphicDrawModal,
} from "@/components/drive/richtext/docs-graphic-draw-modal"
import {
  DOCS_GRAPHIC_OPTIONS_EVENT,
  DOCS_GRAPHIC_OPTIONS_SIDEBAR_WIDTH_PX,
  DocsGraphicOptionsSidebar,
} from "@/components/drive/richtext/docs-graphic-options-sidebar"
import { cn } from "@/lib/utils"

export function DocsEditorWorkspace({
  editor,
  pageLayout,
  zoom,
  editable,
  showLayout,
  showRuler,
  showNonPrintableChars,
  editorMode,
  outlineExpanded,
  onToggleOutline,
  onPageCountChange,
  onCurrentPageChange,
  toolbar,
  toolbarShellClassName,
  onRegionContentChange,
  onPageSetupChange,
  onRegionEditorChange,
  onPageStackReady,
}: {
  editor: Editor
  pageLayout: DocPageLayout
  zoom: number
  editable: boolean
  showLayout: boolean
  showRuler: boolean
  showNonPrintableChars: boolean
  editorMode: "edit" | "suggest" | "view"
  outlineExpanded?: boolean
  onToggleOutline?: () => void
  onPageCountChange?: (count: number) => void
  onCurrentPageChange?: (page: number) => void
  toolbar?: ReactNode
  toolbarShellClassName?: string
  onRegionContentChange?: (
    region: "header" | "footer",
    content: Record<string, unknown>,
    meta: { pageIndex: number; contentHeightPx: number }
  ) => void
  onPageSetupChange?: (
    patch: Partial<import("@/lib/drive/doc-page-setup").DocPageSetup>,
    options?: { immediate?: boolean }
  ) => void
  onRegionEditorChange?: (editor: import("@tiptap/react").Editor | null) => void
  onPageStackReady?: (getPageStack: () => HTMLElement | null) => void
}) {
  const canvasRef = useRef<HTMLDivElement>(null)
  const rulerTrackRef = useRef<HTMLDivElement>(null)
  const [pageCount, setPageCount] = useState(1)
  const [narrowViewport, setNarrowViewport] = useState(false)
  const [graphicOptionsOpen, setGraphicOptionsOpen] = useState(false)
  const [graphicOptionsSection, setGraphicOptionsSection] =
    useState<import("@/lib/drive/docs-graphic-ui").DocsGraphicOptionsSection | null>(null)
  const [graphicDrawOpen, setGraphicDrawOpen] = useState(false)

  useEffect(() => {
    const onOpenOptions = (event: Event) => {
      const detail = (event as CustomEvent<{ section?: import("@/lib/drive/docs-graphic-ui").DocsGraphicOptionsSection }>).detail
      setGraphicOptionsSection(detail?.section ?? null)
      setGraphicOptionsOpen(true)
    }
    const onOpenDraw = () => setGraphicDrawOpen(true)
    window.addEventListener(DOCS_GRAPHIC_OPTIONS_EVENT, onOpenOptions)
    window.addEventListener(DOCS_GRAPHIC_DRAW_EVENT, onOpenDraw)
    return () => {
      window.removeEventListener(DOCS_GRAPHIC_OPTIONS_EVENT, onOpenOptions)
      window.removeEventListener(DOCS_GRAPHIC_DRAW_EVENT, onOpenDraw)
    }
  }, [])

  const rulersVisible = showLayout && showRuler
  const scale = docsZoomToScale(zoom)
  const showToolbarShell = Boolean(toolbar) || rulersVisible
  const marginsEditable = editable && editorMode !== "view"
  const graphicOptionsSidebarOpen =
    graphicOptionsOpen && editable && editorMode !== "view"
  const graphicOptionsSidebarInset = graphicOptionsSidebarOpen
    ? DOCS_GRAPHIC_OPTIONS_SIDEBAR_WIDTH_PX
    : 0

  const {
    pageLayoutWithMargins,
    beginMarginDrag,
    moveMarginDrag,
    endMarginDrag,
    dragTooltip,
  } = useDocsRulerMarginDrag({
    pageLayout,
    editable: marginsEditable,
    onPageSetupChange,
  })

  const rulerSync = useDocsRulerSync({
    canvasRef,
    rulerTrackRef,
    editor,
    pageLayout: pageLayoutWithMargins,
    zoom,
    pageCount,
    narrowViewport,
  })

  useEffect(() => {
    onCurrentPageChange?.(rulerSync.currentPage + 1)
  }, [onCurrentPageChange, rulerSync.currentPage])

  useEffect(() => {
    onPageStackReady?.(
      () => canvasRef.current?.querySelector<HTMLElement>("[data-docs-page-stack]") ?? null
    )
  }, [onPageStackReady, pageCount, showLayout, zoom])

  return (
    <div className="docs-editor-workspace flex min-h-0 flex-1 flex-col">
      <DocsRulerMarginDragTooltip tooltip={dragTooltip} />
      <DocsGraphicFloatingToolbar
        editor={editor}
        canvasRef={canvasRef}
        disabled={!editable || editorMode === "view"}
      />
      <DocsTableFloatingToolbar
        editor={editor}
        canvasRef={canvasRef}
        disabled={!editable || editorMode === "view"}
      />
      <DocsGraphicDrawModal
        editor={editor}
        open={graphicDrawOpen && editable && editorMode !== "view"}
        onClose={() => setGraphicDrawOpen(false)}
      />
      {showToolbarShell ? (
        <div
          className={cn(
            "docs-toolbar-shell shrink-0",
            toolbarShellClassName
          )}
        >
          {toolbar}
          {rulersVisible ? (
            <DocsRulerToolbarRow
              pageLayout={pageLayoutWithMargins}
              scale={scale}
              rulerSync={rulerSync}
              rulerTrackRef={rulerTrackRef}
              contentInsetRight={graphicOptionsSidebarInset}
              outlineExpanded={outlineExpanded}
              onToggleOutline={onToggleOutline}
              editable={marginsEditable}
              onMarginDragStart={beginMarginDrag}
              onMarginDrag={moveMarginDrag}
              onMarginDragEnd={endMarginDrag}
            />
          ) : null}
        </div>
      ) : null}

      <div className="relative min-h-0 flex-1 overflow-hidden">
        {rulersVisible ? (
          <DocsRulersLeftRail
            pageLayout={pageLayoutWithMargins}
            scale={scale}
            rulerSync={rulerSync}
            editable={marginsEditable}
            onMarginDragStart={beginMarginDrag}
            onMarginDrag={moveMarginDrag}
            onMarginDragEnd={endMarginDrag}
          />
        ) : null}

        <div
          className="flex h-full min-h-0 flex-row"
          style={
            rulersVisible
              ? { paddingLeft: DOCS_VERTICAL_RULER_WIDTH_PX }
              : undefined
          }
        >
          <div className="flex h-full min-h-0 min-w-0 flex-1 flex-col">
            <DocsPageView
              editor={editor}
              pageLayout={pageLayoutWithMargins}
              zoom={zoom}
              editable={editable}
              showLayout={showLayout}
              showRuler={false}
              showNonPrintableChars={showNonPrintableChars}
              editorMode={editorMode}
              canvasRef={canvasRef}
              onPageCountChange={(count) => {
                setPageCount(count)
                onPageCountChange?.(count)
              }}
              onNarrowViewportChange={setNarrowViewport}
              onRegionContentChange={onRegionContentChange}
              onPageSetupChange={onPageSetupChange}
              onRegionEditorChange={onRegionEditorChange}
            />
          </div>
          <DocsGraphicOptionsSidebar
            editor={editor}
            pageLayout={pageLayoutWithMargins}
            open={graphicOptionsSidebarOpen}
            focusSection={graphicOptionsSection}
            onClose={() => {
              setGraphicOptionsOpen(false)
              setGraphicOptionsSection(null)
            }}
          />
        </div>
      </div>
    </div>
  )
}
