import { useState as o, useCallback as n } from "react";
import { useEditor as Te } from "@tiptap/react";
import Ce from "@tiptap/starter-kit";
import Re from "@tiptap/extension-text-align";
import { TableRow as be } from "@tiptap/extension-table-row";
import { TableCell as ve } from "@tiptap/extension-table-cell";
import { TableHeader as xe } from "@tiptap/extension-table-header";
import { Table as Ie } from "@tiptap/extension-table";
import { DEFAULT_FONT_SIZE as He } from "../constants/index.js";
import ke from "./useHtmlEditorState.js";
import we from "./useHtmlEditorLinkAction.js";
import Le from "./useHtmlEditorImageAction.js";
import Be from "./useHtmlEditorSearchAction.js";
import Pe from "./useHtmlEditorColorAction.js";
import ze from "./useHtmlEditorFontSizeAction.js";
import ye from "./useHtmlEditorVideoAction.js";
import Fe from "../extensions/fontSizeExtension.js";
import Ee from "../extensions/textColorExtension.js";
import Ve from "../extensions/bgColorExtension.js";
import Ue from "../extensions/imageExtension.js";
import Me from "../extensions/videoExtension.js";
import Oe from "../extensions/openLinkOnModClickExtension.js";
import { SearchAndReplaceExtension as De } from "../extensions/searchAndReplaceExtension.js";
import c from "../utils/getToolbarSnapshot.js";
function mt({ initialContent: D, onContentChange: r, initialMode: _, colorPalette: W }) {
  const { mode: q, setMode: a } = ke(_), [N, d] = o(!1), [j, u] = o(!1), J = n(() => {
    d(!1), u(!1);
  }, []), [K, Z] = o([]), [G, Q] = o("body"), [X, Y] = o(He), [$, ee] = o(void 0), [te, oe] = o(void 0), [le, ne] = o("alignLeft"), [m, re] = o(null), [ie, se] = o(""), [ce, h] = o(null), [ae, de] = o(null), [ue, g] = o(null), [f, me] = o(""), [he, p] = o(0), [ge, S] = o(0), i = n((t) => {
    Z(t.activeActions), Q(t.selectedStyle), Y(t.selectedFontSize), ee(t.selectedTextColor), oe(t.selectedBgColor), ne(t.selectedAlignment), re(t.selectedLink), se(t.selectedText), h(t.selectedImage), de(t.selectedVideo), g(t.selectedTable);
  }, []), e = Te({
    // TipTap v3: Prevent immediate render to avoid hydration mismatches in SSR frameworks.
    // This ensures the editor only renders after client-side hydration is complete.
    immediatelyRender: !1,
    extensions: [
      // Configure heading to support levels 1–4 (default is 1–3).
      // TipTap v3: StarterKit now includes link and underline by default, so we disable them
      // here to use our custom configurations below.
      Ce.configure({
        heading: {
          levels: [1, 2, 3, 4]
        },
        link: {
          openOnClick: !1,
          HTMLAttributes: {
            class: "html-editor-link",
            rel: "noopener noreferrer",
            target: "_blank"
          }
        }
      }),
      // Custom mark for font-size inline styling.
      Fe,
      // Custom marks for foreground and background color inline styling.
      Ee,
      Ve,
      // Custom image node with alignment support.
      Ue,
      // Custom video node with alignment support and embed detection (YouTube, Vimeo).
      Me,
      // Block-level text alignment (left / center / right / justify).
      // Applies a text-align style to paragraph, heading, and table cell nodes.
      Re.configure({ types: ["heading", "paragraph", "tableCell", "tableHeader"] }),
      // Enables Ctrl/Cmd+Click to open links in a new tab.
      // Must be registered after Link so the link mark type exists in the schema.
      Oe,
      // Custom Table extension with related node types.
      // Enables table creation, editing, and manipulation with resizable columns.
      Ie.configure({
        resizable: !0
      }),
      be,
      xe,
      ve,
      // Search and replace extension for finding and replacing text in the editor.
      De
    ],
    content: D,
    // Style the contenteditable ProseMirror div directly via editorProps.
    // TipTap best practice: set attributes here rather than targeting .ProseMirror via CSS.
    editorProps: {
      attributes: {
        class: "p-[var(--spacing-4)] min-h-[var(--spacing-50)] outline-none"
      },
      // Intercept paste events that contain raw image data (e.g. screenshots from clipboard).
      // TipTap/ProseMirror would otherwise embed them as base64 strings, which is unwanted.
      // Instead: block the paste, show a warning, and open the image URL popover.
      handlePaste: (t, l) => {
        var O;
        return Array.from(((O = l.clipboardData) == null ? void 0 : O.items) ?? []).some((Ae) => Ae.type.startsWith("image/")) ? (d(!0), u(!0), !0) : !1;
      }
    },
    // Fires on every content change. Only place that notifies the parent.
    // Also syncs toolbar state because content changes move the selection.
    onUpdate: ({ editor: t }) => {
      r == null || r(t.getHTML()), i(c(t)), f && (p(t.storage.searchAndReplace.results.length), S(t.storage.searchAndReplace.resultIndex));
    },
    // Fires on every cursor / selection move inside the editor.
    // Keeps toolbar in sync when the user navigates between lines
    // without typing (no content change → onUpdate would not fire).
    onSelectionUpdate: ({ editor: t }) => {
      i(c(t));
    },
    // Fires when the content editable re-gains focus after the user clicked
    // away (e.g. interacted with a popover or another element).
    // onSelectionUpdate is not guaranteed in that case, so onFocus is the
    // reliable fallback that keeps the toolbar and typography popover in sync.
    onFocus: ({ editor: t }) => {
      i(c(t));
    }
  }), { handleLink: A, handleUnlink: T } = we(e, m), { handleInsertImage: C, handleUpdateImageAlignment: R, handleUpdateImageAlt: b, handleDeleteImage: v } = Le(e), {
    handleSetSearchTerm: x,
    handleSetReplaceTerm: I,
    handleNextSearchResult: H,
    handlePreviousSearchResult: k,
    handleReplace: w,
    handleReplaceAll: L,
    handleResetSearch: B
  } = Be(e, me, p, S), { handleTextColor: P, handleBgColor: z, handleResetTextColor: y, handleResetBgColor: F } = Pe(e), { handleFontSize: E } = ze(e), { handleInsertVideo: V, handleUpdateVideoAlignment: U, handleDeleteVideo: M } = ye(e), fe = n(
    (t, l) => {
      if (!e) return;
      const s = {
        // --- History ---
        undo: () => e.chain().focus().undo().run(),
        redo: () => e.chain().focus().redo().run(),
        // --- Typography / block-level styles ---
        h1: () => (e.isActive("heading", { level: 1 }) ? e.chain().focus().setParagraph() : e.chain().focus().setHeading({ level: 1 })).run(),
        h2: () => (e.isActive("heading", { level: 2 }) ? e.chain().focus().setParagraph() : e.chain().focus().setHeading({ level: 2 })).run(),
        h3: () => (e.isActive("heading", { level: 3 }) ? e.chain().focus().setParagraph() : e.chain().focus().setHeading({ level: 3 })).run(),
        h4: () => (e.isActive("heading", { level: 4 }) ? e.chain().focus().setParagraph() : e.chain().focus().setHeading({ level: 4 })).run(),
        body: () => e.chain().focus().setParagraph().unsetMark("fontSize").run(),
        small: () => e.chain().focus().setParagraph().setMark("fontSize", { size: "14" }).run(),
        // --- Inline formatting ---
        bold: () => e.chain().focus().toggleBold().run(),
        italic: () => e.chain().focus().toggleItalic().run(),
        underline: () => e.chain().focus().toggleUnderline().run(),
        strikethrough: () => e.chain().focus().toggleStrike().run(),
        // --- Lists ---
        bulletList: () => e.chain().focus().toggleBulletList().run(),
        numberedList: () => e.chain().focus().toggleOrderedList().run(),
        // --- Blocks ---
        horizontalRule: () => e.chain().focus().setHorizontalRule().run(),
        blockquote: () => e.chain().focus().toggleBlockquote().run(),
        // --- Text alignment ---
        alignLeft: () => e.chain().focus().setTextAlign("left").run(),
        alignCenter: () => e.chain().focus().setTextAlign("center").run(),
        alignRight: () => e.chain().focus().setTextAlign("right").run(),
        alignJustify: () => e.chain().focus().setTextAlign("justify").run(),
        // --- Table manipulation ---
        insertTable: () => e.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: !0 }).run(),
        addColumnBefore: () => e.chain().focus().addColumnBefore().run(),
        addColumnAfter: () => e.chain().focus().addColumnAfter().run(),
        deleteColumn: () => e.chain().focus().deleteColumn().run(),
        addRowBefore: () => e.chain().focus().addRowBefore().run(),
        addRowAfter: () => e.chain().focus().addRowAfter().run(),
        deleteRow: () => e.chain().focus().deleteRow().run(),
        deleteTable: () => e.chain().focus().deleteTable().run(),
        mergeCells: () => e.chain().focus().mergeCells().run(),
        splitCell: () => e.chain().focus().splitCell().run(),
        toggleHeaderRow: () => e.chain().focus().toggleHeaderRow().run(),
        toggleHeaderColumn: () => e.chain().focus().toggleHeaderColumn().run(),
        // --- Specialized Actions (Delegated) ---
        fontSize: () => E(l),
        textColor: () => P(l),
        bgColor: () => z(l),
        resetTextColor: () => y(),
        resetBgColor: () => F(),
        link: () => A(l),
        unlink: () => T(),
        insertImage: () => C(l),
        imageAlignment: () => R(l),
        imageAlt: () => b(l),
        deleteImage: () => v(),
        setSearchTerm: () => x(l),
        setReplaceTerm: () => I(l),
        nextSearchResult: () => H(),
        previousSearchResult: () => k(),
        replace: () => w(),
        replaceAll: () => L(),
        resetSearch: () => B(),
        insertVideo: () => V(l),
        videoAlignment: () => U(l),
        deleteVideo: () => M()
      };
      s[t] && s[t]();
    },
    [
      e,
      E,
      P,
      z,
      y,
      F,
      A,
      T,
      C,
      R,
      b,
      v,
      x,
      I,
      H,
      k,
      w,
      L,
      B,
      V,
      U,
      M
    ]
  ), pe = n(
    (t) => {
      e && e.commands.setContent(t);
    },
    [e]
  ), Se = n(
    (t) => {
      a(t), h(null), g(null), e && e.chain().setTextSelection(0).run();
    },
    [a, e]
  );
  return {
    editor: e,
    mode: q,
    handleModeChange: Se,
    handleToolbarAction: fe,
    // Image paste warning — shown when the user tries to paste an image from clipboard.
    showImagePasteWarning: N,
    imagePopoverOpen: j,
    handleImagePopoverClose: J,
    // HTML code sync — updates TipTap content when code editor changes.
    // Used by CodeEditor's onChange prop in code mode.
    handleCodeChange: pe,
    // Toolbar state
    activeActions: K,
    selectedStyle: G,
    selectedFontSize: X,
    selectedTextColor: $,
    selectedBgColor: te,
    selectedAlignment: le,
    colorPalette: W,
    // Link state — contains existing link data when cursor is on a link,
    // or null when not on a link. Used by HtmlEditorLinkAction popover.
    selectedLink: m,
    // Selected text — the currently highlighted text in the editor.
    // Used to pre-fill display text when creating a new link.
    selectedText: ie,
    // Image state — contains image data when cursor is on an image node,
    // or null when not on an image. Used by HtmlEditorImageAction popover.
    selectedImage: ce,
    // Video state — contains video data when cursor is on a video node,
    // or null when not on a video. Used by HtmlEditorVideoAction popover.
    selectedVideo: ae,
    // Table state — contains table metadata when cursor is inside a table,
    // or null when not in a table. Used by HtmlEditorTableBubbleMenu.
    selectedTable: ue,
    // Search and replace state — tracks search term, results count, and current result index.
    // Used by HtmlEditorSearchAction and HtmlEditorReplaceAction popovers.
    searchTerm: f,
    searchResults: he,
    searchResultIndex: ge
  };
}
export {
  mt as default
};
//# sourceMappingURL=useHtmlEditor.js.map
