"use client"

import { useEffect, useMemo, useState } from "react"
import type { Editor } from "@tiptap/react"
import type {
  DocsFormatMenuActions,
  DocsFormatMenuState,
} from "@/components/drive/richtext/docs-format-menu"
import { applyDocsParagraphStyleById, readActiveParagraphStyleId } from "@/lib/drive/docs-paragraph-style-apply"
import {
  docsClearTableCellBorders,
  docsDefaultTableBorder,
  docsSetTableAlignment,
  docsSetTableCellBackground,
  docsSetTableCellBordersAll,
  docsSetTableRowHeight,
  docsTableCanMerge,
  docsTableCanSplit,
} from "@/lib/drive/docs-table-actions"
import {
  readDocsCustomSpacingDraft,
  readDocsParagraphSpacingState,
  setDocsCustomSpacing,
} from "@/lib/drive/docs-line-spacing-actions"
import { DOCS_DEFAULT_PARAGRAPH_SPACING } from "@/lib/drive/docs-line-spacing"
import {
  readDocsListState,
} from "@/lib/drive/docs-list-actions"

export function useDocsFormatMenu({
  editor,
  disabled,
  onPageSetup,
}: {
  editor: Editor | null
  disabled?: boolean
  onPageSetup?: () => void
}) {
  const [revision, setRevision] = useState(0)

  useEffect(() => {
    if (!editor || disabled) return

    const refresh = () => setRevision((value) => value + 1)
    editor.on("transaction", refresh)
    editor.on("selectionUpdate", refresh)
    return () => {
      editor.off("transaction", refresh)
      editor.off("selectionUpdate", refresh)
    }
  }, [disabled, editor])

  const state = useMemo<DocsFormatMenuState>(() => {
    if (!editor) {
      return {
        isBold: false,
        isItalic: false,
        isUnderline: false,
        isStrike: false,
        alignLeft: true,
        alignCenter: false,
        alignRight: false,
        alignJustify: false,
        isBulletList: false,
        isOrderedList: false,
        styleId: "normal",
        tableSelected: false,
        tableCanMerge: false,
        tableCanSplit: false,
        graphicSelected: false,
        imageSelected: false,
        lineHeightPresetId: "1.15",
        hasSpaceBefore: false,
        hasSpaceAfter: false,
        keepWithNext: false,
        keepLinesTogether: false,
        preventWidowOrphan: false,
        pageBreakBefore: false,
        customSpacingDraft: { ...DOCS_DEFAULT_PARAGRAPH_SPACING },
        isTaskList: false,
        bulletStyleId: null,
        orderedStyleId: null,
        checklistStyleId: null,
        orderedListStart: 1,
      }
    }

    let styleId = readActiveParagraphStyleId(editor)
    const spacing = readDocsParagraphSpacingState(editor)
    const listState = readDocsListState(editor)

    return {
      isBold: editor.isActive("bold"),
      isItalic: editor.isActive("italic"),
      isUnderline: editor.isActive("underline"),
      isStrike: editor.isActive("strike"),
      alignLeft: editor.isActive({ textAlign: "left" }),
      alignCenter: editor.isActive({ textAlign: "center" }),
      alignRight: editor.isActive({ textAlign: "right" }),
      alignJustify: editor.isActive({ textAlign: "justify" }),
      isBulletList: editor.isActive("bulletList"),
      isOrderedList: editor.isActive("orderedList"),
      styleId,
      tableSelected: editor.isActive("table"),
      tableCanMerge: docsTableCanMerge(editor),
      tableCanSplit: docsTableCanSplit(editor),
      graphicSelected:
        editor.isActive("docsGraphic") || editor.isActive("docsInlineGraphic"),
      imageSelected: editor.isActive("image"),
      lineHeightPresetId: spacing.lineHeightPresetId,
      hasSpaceBefore: spacing.hasSpaceBefore,
      hasSpaceAfter: spacing.hasSpaceAfter,
      keepWithNext: spacing.keepWithNext,
      keepLinesTogether: spacing.keepLinesTogether,
      preventWidowOrphan: spacing.preventWidowOrphan,
      pageBreakBefore: spacing.pageBreakBefore,
      customSpacingDraft: readDocsCustomSpacingDraft(editor),
      isTaskList: listState.isTaskList,
      bulletStyleId: listState.bulletStyleId,
      orderedStyleId: listState.orderedStyleId,
      checklistStyleId: listState.checklistStyleId,
      orderedListStart: listState.orderedStart,
    }
  }, [editor, revision])

  const actions = useMemo<DocsFormatMenuActions>(
    () => ({
      onBold: () => editor?.chain().focus().toggleMark("bold").run(),
      onItalic: () => editor?.chain().focus().toggleMark("italic").run(),
      onUnderline: () => editor?.chain().focus().toggleUnderline().run(),
      onStrike: () => editor?.chain().focus().toggleMark("strike").run(),
      onAlignLeft: () => editor?.chain().focus().setTextAlign("left").run(),
      onAlignCenter: () => editor?.chain().focus().setTextAlign("center").run(),
      onAlignRight: () => editor?.chain().focus().setTextAlign("right").run(),
      onAlignJustify: () => editor?.chain().focus().setTextAlign("justify").run(),
      onIncreaseIndent: () => {
        if (!editor) return
        editor.chain().focus().increaseDocsIndent().run()
      },
      onDecreaseIndent: () => {
        if (!editor) return
        editor.chain().focus().decreaseDocsIndent().run()
      },
      onToggleBulletList: () => editor?.chain().focus().toggleBulletList().run(),
      onToggleOrderedList: () => editor?.chain().focus().toggleOrderedList().run(),
      onApplyStyle: (styleId) => {
        if (!editor) return
        applyDocsParagraphStyleById(editor, styleId)
      },
      onClearFormatting: () =>
        editor?.chain().focus().unsetAllMarks().clearNodes().run(),
      onPageSetup,
      onTableAddRowBefore: () => editor?.chain().focus().addRowBefore().run(),
      onTableAddRowAfter: () => editor?.chain().focus().addRowAfter().run(),
      onTableAddColumnBefore: () => editor?.chain().focus().addColumnBefore().run(),
      onTableAddColumnAfter: () => editor?.chain().focus().addColumnAfter().run(),
      onTableDeleteRow: () => editor?.chain().focus().deleteRow().run(),
      onTableDeleteColumn: () => editor?.chain().focus().deleteColumn().run(),
      onTableDelete: () => editor?.chain().focus().deleteTable().run(),
      onTableMergeCells: () => editor?.chain().focus().mergeCells().run(),
      onTableSplitCell: () => editor?.chain().focus().splitCell().run(),
      onTableToggleHeaderRow: () => editor?.chain().focus().toggleHeaderRow().run(),
      onTableToggleHeaderColumn: () => editor?.chain().focus().toggleHeaderColumn().run(),
      onTableSetCellBackground: (color) => docsSetTableCellBackground(editor, color),
      onTableAlignLeft: () => docsSetTableAlignment(editor, "left"),
      onTableAlignCenter: () => docsSetTableAlignment(editor, "center"),
      onTableAlignRight: () => docsSetTableAlignment(editor, "right"),
      onTableFixStructure: () => editor?.chain().focus().fixTables().run(),
      onTableSetCellBorders: (color) =>
        docsSetTableCellBordersAll(editor, docsDefaultTableBorder(color)),
      onTableClearCellBorders: () => docsClearTableCellBorders(editor),
      onTableSetRowHeight: (height) => docsSetTableRowHeight(editor, height),
      onSetLineHeight: (lineHeight) => {
        if (!editor) return
        editor.chain().focus().setDocsLineHeight(lineHeight).run()
      },
      onToggleSpaceBefore: () => {
        if (!editor) return
        editor.chain().focus().toggleDocsSpaceBefore().run()
      },
      onToggleSpaceAfter: () => {
        if (!editor) return
        editor.chain().focus().toggleDocsSpaceAfter().run()
      },
      onApplyCustomSpacing: (input) => {
        if (!editor) return
        setDocsCustomSpacing(editor, input)
      },
      onToggleKeepWithNext: () => {
        if (!editor) return
        editor.chain().focus().toggleDocsKeepWithNext().run()
      },
      onToggleKeepLinesTogether: () => {
        if (!editor) return
        editor.chain().focus().toggleDocsKeepLinesTogether().run()
      },
      onTogglePreventWidowOrphan: () => {
        if (!editor) return
        editor.chain().focus().toggleDocsPreventWidowOrphan().run()
      },
      onTogglePageBreakBefore: () => {
        if (!editor) return
        editor.chain().focus().toggleDocsPageBreakBefore().run()
      },
      onApplyBulletStyle: (styleId) => {
        if (!editor) return
        editor.chain().focus().applyDocsBulletStyle(styleId).run()
      },
      onApplyOrderedStyle: (styleId) => {
        if (!editor) return
        editor.chain().focus().applyDocsOrderedStyle(styleId).run()
      },
      onApplyChecklistStyle: (styleId) => {
        if (!editor) return
        editor.chain().focus().applyDocsChecklistStyle(styleId).run()
      },
      onRestartOrderedList: () => {
        if (!editor) return
        editor.chain().focus().restartDocsOrderedList().run()
      },
      onContinueOrderedList: () => {
        if (!editor) return
        editor.chain().focus().continueDocsOrderedList().run()
      },
      onSetOrderedListStart: (start) => {
        if (!editor) return
        editor.chain().focus().setDocsOrderedListStart(start).run()
      },
    }),
    [editor, onPageSetup]
  )

  return {
    actions,
    state,
    disabled,
  }
}
