import { jsxs, jsx } from 'react/jsx-runtime';
import React__default, { useState, useCallback, useRef, useMemo, useEffect } from 'react';
import { createPortal } from 'react-dom';
import { useReducedMotion, AnimatePresence, motion } from 'motion/react';
import { FormLabel } from '../FormLabel/FormLabel.js';
import { richTextEditorTheme, colorOptions } from './RichTextEditor.theme.js';
import { floatingToolbarVariants } from './RichTextEditor.animations.js';
import { cn } from '../../../utils/cn.js';
import { Button } from '../../core/Button/Button.js';
import { ArrowUturnRightIcon, ArrowUturnLeftIcon, Bars3BottomRightIcon, Bars3Icon, Bars3BottomLeftIcon, UnderlineIcon, ItalicIcon, BoldIcon } from '@heroicons/react/24/outline';
import { useSelectPortal } from '../../../hooks/useSelectPortal.js';
import { PaintBrushIcon } from '@heroicons/react/24/solid';
import { createDropdownAnimations } from '../Select/Select.animations.js';
import { useIsClient } from '../../../hooks/useIsClient.js';

const FONT_SIZE_OPTIONS = [
    { key: "xs", label: "XS", value: "0.75rem", px: 12 },
    { key: "sm", label: "SM", value: "0.875rem", px: 14 },
    { key: "md", label: "MD", value: "1rem", px: 16 },
    { key: "lg", label: "LG", value: "1.125rem", px: 18 },
    { key: "xl", label: "XL", value: "1.25rem", px: 20 },
    { key: "2xl", label: "2XL", value: "1.5rem", px: 24 },
    { key: "3xl", label: "3XL", value: "1.875rem", px: 30 },
    { key: "4xl", label: "4XL", value: "2.25rem", px: 36 },
];
const FONT_SIZE_COMMAND_VALUE = {
    xs: "1",
    sm: "2",
    md: "3",
    lg: "4",
    xl: "5",
    "2xl": "6",
    "3xl": "7",
    "4xl": "7",
};
const getFontSizeOption = (key) => { var _a; return (_a = FONT_SIZE_OPTIONS.find((option) => option.key === key)) !== null && _a !== void 0 ? _a : FONT_SIZE_OPTIONS[2]; };
const getClosestFontSizeKey = (px) => {
    let closest = "md";
    let minDiff = Number.POSITIVE_INFINITY;
    FONT_SIZE_OPTIONS.forEach((option) => {
        const diff = Math.abs(option.px - px);
        if (diff < minDiff) {
            minDiff = diff;
            closest = option.key;
        }
    });
    return closest;
};
const DEFAULT_FORMATTING_STATE = {
    bold: false,
    italic: false,
    underline: false,
    textAlign: "left",
    fontSize: "md",
    textColor: "#000000",
};
const DEFAULT_TOOLBAR = {
    show: true,
    position: "top",
    tools: [
        "bold",
        "italic",
        "underline",
        "separator",
        "fontSize",
        "textColor",
        "separator",
        "alignLeft",
        "alignCenter",
        "alignRight",
        "separator",
        "undo",
        "redo",
    ],
};
const RichTextEditor = React__default.forwardRef(({ size = "md", state = "default", className = "", label, labelClassName = "", helperText, helperTextClassName = "", value = "", onChange, placeholder = "Start typing...", id, required, minHeight = 120, maxHeight, toolbar: toolbarProp = DEFAULT_TOOLBAR, theme = {}, sanitize, ...props }, ref) => {
    const [isFocused, setIsFocused] = useState(false);
    const [showToolbar, setShowToolbar] = useState(false);
    const [toolbarPosition, setToolbarPosition] = useState({ top: 0, left: 0 });
    const [formattingState, setFormattingState] = useState(DEFAULT_FORMATTING_STATE);
    const [showFontSizePicker, setShowFontSizePicker] = useState(false);
    const [showColorPicker, setShowColorPicker] = useState(false);
    const shouldReduceMotion = useReducedMotion();
    const isClient = useIsClient();
    // Built-in basic sanitizer: strips <script> tags and on* event handlers
    const sanitizeHtml = useCallback((html) => {
        if (sanitize)
            return sanitize(html);
        // Basic sanitization — strips script tags and inline event handlers
        return html
            .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
            .replace(/\bon\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '');
    }, [sanitize]);
    const editorRef = useRef(null);
    const toolbarRef = useRef(null);
    const fontSizeTriggerRef = useRef(null);
    const colorTriggerRef = useRef(null);
    const generatedId = React__default.useId();
    const editorId = id || generatedId;
    const themeStyles = useMemo(() => {
        var _a, _b;
        return ({
            ...richTextEditorTheme,
            ...theme,
            sizes: {
                ...richTextEditorTheme.sizes,
                ...((_a = theme === null || theme === void 0 ? void 0 : theme.sizes) !== null && _a !== void 0 ? _a : {}),
            },
            states: {
                ...richTextEditorTheme.states,
                ...((_b = theme === null || theme === void 0 ? void 0 : theme.states) !== null && _b !== void 0 ? _b : {}),
            },
        });
    }, [theme]);
    const toolbarConfig = useMemo(() => {
        var _a, _b, _c;
        const base = {
            show: (_a = DEFAULT_TOOLBAR.show) !== null && _a !== void 0 ? _a : true,
            position: (_b = DEFAULT_TOOLBAR.position) !== null && _b !== void 0 ? _b : "top",
            tools: [...((_c = DEFAULT_TOOLBAR.tools) !== null && _c !== void 0 ? _c : [])],
            className: DEFAULT_TOOLBAR.className,
        };
        if (toolbarProp) {
            if (typeof toolbarProp.show === "boolean") {
                base.show = toolbarProp.show;
            }
            if (toolbarProp.position) {
                base.position = toolbarProp.position;
            }
            if (toolbarProp.tools) {
                base.tools = [...toolbarProp.tools];
            }
            if (typeof toolbarProp.className === "string") {
                base.className = toolbarProp.className;
            }
        }
        return base;
    }, [toolbarProp]);
    const { position: fontSizePortalPosition, cssVariables: fontSizePortalCssVars, contentRef: fontSizePortalContentRef, isReady: fontSizePortalReady, isFlipped: fontSizeIsFlipped, } = useSelectPortal({
        triggerRef: fontSizeTriggerRef,
        isOpen: showFontSizePicker,
        placement: "bottom-start",
        offset: 6,
        autoWidth: true,
    });
    const { position: colorPortalPosition, cssVariables: colorPortalCssVars, contentRef: colorPortalContentRef, isReady: colorPortalReady, isFlipped: colorIsFlipped, } = useSelectPortal({
        triggerRef: colorTriggerRef,
        isOpen: showColorPicker,
        placement: "bottom-start",
        offset: 6,
        autoWidth: true,
    });
    const isDisabled = state === "disabled";
    const isInvalid = state === "invalid";
    const getDataState = () => {
        if (isDisabled)
            return "disabled";
        if (isInvalid)
            return "invalid";
        if (isFocused)
            return "focus";
        return "default";
    };
    const focusEditor = useCallback(() => {
        if (editorRef.current && document.activeElement !== editorRef.current) {
            editorRef.current.focus();
        }
    }, []);
    const getCurrentFontSize = useCallback(() => {
        if (!editorRef.current)
            return DEFAULT_FORMATTING_STATE.fontSize;
        const selection = window.getSelection();
        if (!selection || selection.rangeCount === 0) {
            const editorComputed = window.getComputedStyle(editorRef.current);
            const editorSize = parseFloat(editorComputed.fontSize || "");
            return Number.isFinite(editorSize)
                ? getClosestFontSizeKey(editorSize)
                : DEFAULT_FORMATTING_STATE.fontSize;
        }
        const range = selection.getRangeAt(0);
        let node = range.startContainer;
        if (node.nodeType === Node.TEXT_NODE) {
            node = node.parentElement;
        }
        while (node && node !== editorRef.current) {
            if (node instanceof HTMLElement) {
                const computed = window.getComputedStyle(node);
                const size = parseFloat(computed.fontSize || "");
                if (Number.isFinite(size)) {
                    return getClosestFontSizeKey(size);
                }
            }
            node = node ? node.parentNode : null;
        }
        const editorComputed = window.getComputedStyle(editorRef.current);
        const editorSize = parseFloat(editorComputed.fontSize || "");
        return Number.isFinite(editorSize)
            ? getClosestFontSizeKey(editorSize)
            : DEFAULT_FORMATTING_STATE.fontSize;
    }, []);
    const updateFormattingState = useCallback(() => {
        if (!editorRef.current || isDisabled) {
            setFormattingState(DEFAULT_FORMATTING_STATE);
            return;
        }
        let bold = false;
        let italic = false;
        let underline = false;
        let textAlign = "left";
        let fontSize = DEFAULT_FORMATTING_STATE.fontSize;
        let textColor = DEFAULT_FORMATTING_STATE.textColor;
        try {
            bold = document.queryCommandState("bold");
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("queryCommandState bold failed", error);
            }
        }
        try {
            italic = document.queryCommandState("italic");
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("queryCommandState italic failed", error);
            }
        }
        try {
            underline = document.queryCommandState("underline");
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("queryCommandState underline failed", error);
            }
        }
        try {
            if (document.queryCommandState("justifyCenter")) {
                textAlign = "center";
            }
            else if (document.queryCommandState("justifyRight")) {
                textAlign = "right";
            }
            else if (document.queryCommandState("justifyFull")) {
                textAlign = "justify";
            }
            else {
                textAlign = "left";
            }
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("queryCommandState alignment failed", error);
            }
        }
        try {
            fontSize = getCurrentFontSize();
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("Failed to determine font size", error);
            }
        }
        try {
            const colorValue = document.queryCommandValue("foreColor");
            if (typeof colorValue === "string" && colorValue.trim().length > 0) {
                textColor = colorValue;
            }
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("queryCommandValue foreColor failed", error);
            }
        }
        setFormattingState({
            bold,
            italic,
            underline,
            textAlign,
            fontSize,
            textColor,
        });
    }, [getCurrentFontSize, isDisabled]);
    const handleContentChange = useCallback(() => {
        if (!editorRef.current || !onChange)
            return;
        onChange(editorRef.current.innerHTML);
    }, [onChange]);
    const execEditorCommand = useCallback((command, value) => {
        if (isDisabled || !editorRef.current)
            return;
        focusEditor();
        try {
            document.execCommand(command, false, value);
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn(`execCommand ${command} failed`, error);
            }
        }
        requestAnimationFrame(() => {
            updateFormattingState();
            handleContentChange();
        });
    }, [focusEditor, handleContentChange, isDisabled, updateFormattingState]);
    const normalizeFontSizeSelection = useCallback((sizeKey) => {
        if (!editorRef.current)
            return;
        const option = getFontSizeOption(sizeKey);
        const selection = window.getSelection();
        if (!selection || selection.rangeCount === 0)
            return;
        const range = selection.getRangeAt(0);
        const value = option.value;
        if (selection.isCollapsed) {
            let node = selection.anchorNode;
            if (node && node.nodeType === Node.TEXT_NODE) {
                node = node.parentElement;
            }
            while (node && node !== editorRef.current) {
                if (node instanceof HTMLElement) {
                    node.style.fontSize = value;
                    if (node.tagName.toLowerCase() === "font") {
                        node.removeAttribute("size");
                    }
                    break;
                }
                node = node.parentElement;
            }
            return;
        }
        const walker = document.createTreeWalker(range.commonAncestorContainer, NodeFilter.SHOW_TEXT, {
            acceptNode: (node) => range.intersectsNode(node) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT,
        });
        const updated = new Set();
        let current;
        while ((current = walker.nextNode())) {
            const parent = current.parentElement;
            if (!parent || !editorRef.current.contains(parent))
                continue;
            if (updated.has(parent))
                continue;
            parent.style.fontSize = value;
            if (parent.tagName.toLowerCase() === "font") {
                parent.removeAttribute("size");
            }
            updated.add(parent);
        }
    }, []);
    const handleUndo = useCallback((event) => {
        event === null || event === void 0 ? void 0 : event.preventDefault();
        event === null || event === void 0 ? void 0 : event.stopPropagation();
        execEditorCommand("undo");
    }, [execEditorCommand]);
    const handleRedo = useCallback((event) => {
        event === null || event === void 0 ? void 0 : event.preventDefault();
        event === null || event === void 0 ? void 0 : event.stopPropagation();
        execEditorCommand("redo");
    }, [execEditorCommand]);
    const handleBold = useCallback((event) => {
        event === null || event === void 0 ? void 0 : event.preventDefault();
        event === null || event === void 0 ? void 0 : event.stopPropagation();
        execEditorCommand("bold");
    }, [execEditorCommand]);
    const handleItalic = useCallback((event) => {
        event === null || event === void 0 ? void 0 : event.preventDefault();
        event === null || event === void 0 ? void 0 : event.stopPropagation();
        execEditorCommand("italic");
    }, [execEditorCommand]);
    const handleUnderline = useCallback((event) => {
        event === null || event === void 0 ? void 0 : event.preventDefault();
        event === null || event === void 0 ? void 0 : event.stopPropagation();
        execEditorCommand("underline");
    }, [execEditorCommand]);
    const handleFontSize = useCallback((sizeKey) => {
        if (isDisabled || !editorRef.current)
            return;
        focusEditor();
        try {
            document.execCommand("styleWithCSS", false, "true");
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("styleWithCSS command failed", error);
            }
        }
        try {
            document.execCommand("fontSize", false, FONT_SIZE_COMMAND_VALUE[sizeKey]);
        }
        catch (error) {
            if (process.env.NODE_ENV !== 'production') {
                console.warn("fontSize command failed", error);
            }
        }
        normalizeFontSizeSelection(sizeKey);
        try {
            document.execCommand("styleWithCSS", false, "false");
        }
        catch (error) {
            // Some browsers do not support toggling this flag; ignore.
        }
        requestAnimationFrame(() => {
            updateFormattingState();
            handleContentChange();
        });
        setShowFontSizePicker(false);
        setShowColorPicker(false);
    }, [
        focusEditor,
        handleContentChange,
        isDisabled,
        normalizeFontSizeSelection,
        updateFormattingState,
    ]);
    const handleTextColor = useCallback((color) => {
        execEditorCommand("foreColor", color);
        setShowColorPicker(false);
        setShowFontSizePicker(false);
    }, [execEditorCommand]);
    const handleAlign = useCallback((alignment) => {
        const commandMap = {
            left: "justifyLeft",
            center: "justifyCenter",
            right: "justifyRight",
        };
        execEditorCommand(commandMap[alignment]);
    }, [execEditorCommand]);
    const handleSelection = useCallback(() => {
        if (!editorRef.current || isDisabled)
            return;
        updateFormattingState();
        if (toolbarConfig.position !== "floating")
            return;
        const selection = window.getSelection();
        if (!selection || selection.rangeCount === 0) {
            setShowToolbar(false);
            return;
        }
        const range = selection.getRangeAt(0);
        if (!editorRef.current.contains(range.commonAncestorContainer) || selection.isCollapsed) {
            setShowToolbar(false);
            return;
        }
        const rect = range.getBoundingClientRect();
        const editorRect = editorRef.current.getBoundingClientRect();
        if (rect.width === 0 && rect.height === 0) {
            setShowToolbar(false);
            return;
        }
        const toolbarWidth = 200;
        const left = Math.max(10, Math.min(rect.left - editorRect.left + rect.width / 2 - toolbarWidth / 2, editorRect.width - toolbarWidth - 10));
        setToolbarPosition({ top: rect.top - editorRect.top - 50, left });
        setShowToolbar(true);
    }, [isDisabled, toolbarConfig.position, updateFormattingState]);
    useEffect(() => {
        if (!editorRef.current)
            return;
        const editor = editorRef.current;
        const handleInput = () => {
            handleContentChange();
            updateFormattingState();
        };
        editor.addEventListener("input", handleInput);
        return () => {
            editor.removeEventListener("input", handleInput);
        };
    }, [handleContentChange, updateFormattingState]);
    useEffect(() => {
        const handleSelectionChange = () => {
            if (!editorRef.current)
                return;
            const selection = window.getSelection();
            if (!selection || selection.rangeCount === 0) {
                setShowToolbar(false);
                updateFormattingState();
                return;
            }
            const range = selection.getRangeAt(0);
            if (!editorRef.current.contains(range.commonAncestorContainer)) {
                setShowToolbar(false);
                return;
            }
            handleSelection();
        };
        document.addEventListener("selectionchange", handleSelectionChange);
        return () => document.removeEventListener("selectionchange", handleSelectionChange);
    }, [handleSelection, updateFormattingState]);
    useEffect(() => {
        const handleClickOutside = (event) => {
            var _a, _b, _c, _d;
            const target = event.target;
            const isInEditor = (_a = editorRef.current) === null || _a === void 0 ? void 0 : _a.contains(target);
            const isInToolbar = (_b = toolbarRef.current) === null || _b === void 0 ? void 0 : _b.contains(target);
            const isInFontSizeDropdown = (_c = fontSizePortalContentRef.current) === null || _c === void 0 ? void 0 : _c.contains(target);
            const isInColorDropdown = (_d = colorPortalContentRef.current) === null || _d === void 0 ? void 0 : _d.contains(target);
            if (!isInEditor && !isInToolbar && !isInFontSizeDropdown && !isInColorDropdown) {
                if (toolbarConfig.position === "floating") {
                    setShowToolbar(false);
                }
                setShowColorPicker(false);
                setShowFontSizePicker(false);
            }
            else if (isInToolbar || isInFontSizeDropdown || isInColorDropdown) {
                const colorMatch = target === null || target === void 0 ? void 0 : target.closest("[data-tool=\"textColor\"]");
                const isColorRelated = Boolean(colorMatch) || isInColorDropdown;
                const fontSizeMatch = target === null || target === void 0 ? void 0 : target.closest("[data-tool=\"fontSize\"]");
                const isFontSizeRelated = isInFontSizeDropdown || Boolean(fontSizeMatch);
                if (!isColorRelated) {
                    setShowColorPicker(false);
                }
                if (!isFontSizeRelated) {
                    setShowFontSizePicker(false);
                }
            }
            else if (isInEditor) {
                setShowColorPicker(false);
                setShowFontSizePicker(false);
            }
        };
        document.addEventListener("mousedown", handleClickOutside);
        return () => document.removeEventListener("mousedown", handleClickOutside);
    }, [toolbarConfig.position]);
    useEffect(() => {
        if (editorRef.current && value !== editorRef.current.innerHTML) {
            editorRef.current.innerHTML = sanitizeHtml(value);
            updateFormattingState();
        }
    }, [updateFormattingState, value, sanitizeHtml]);
    const renderToolbarTool = (tool, index) => {
        var _a, _b;
        const isActive = tool === "bold"
            ? formattingState.bold
            : tool === "italic"
                ? formattingState.italic
                : tool === "underline"
                    ? formattingState.underline
                    : tool === "fontSize"
                        ? formattingState.fontSize !== DEFAULT_FORMATTING_STATE.fontSize
                        : tool === "alignLeft"
                            ? formattingState.textAlign === "left"
                            : tool === "alignCenter"
                                ? formattingState.textAlign === "center"
                                : tool === "alignRight"
                                    ? formattingState.textAlign === "right"
                                    : false;
        const isFloatingToolbar = toolbarConfig.position === "floating";
        const handleMouseDown = (event) => {
            event.preventDefault();
            focusEditor();
        };
        switch (tool) {
            case "bold":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", "data-pressed": isActive ? "true" : "false", onMouseDown: handleMouseDown, onClick: handleBold, disabled: isDisabled, "aria-label": "Bold", "aria-pressed": isActive ? "true" : "false", children: jsx(BoldIcon, { className: "w-4 h-4" }) }, index));
            case "italic":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", "data-pressed": isActive ? "true" : "false", onMouseDown: handleMouseDown, onClick: handleItalic, disabled: isDisabled, "aria-label": "Italic", "aria-pressed": isActive ? "true" : "false", children: jsx(ItalicIcon, { className: "w-4 h-4" }) }, index));
            case "underline":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", "data-pressed": isActive ? "true" : "false", onMouseDown: handleMouseDown, onClick: handleUnderline, disabled: isDisabled, "aria-label": "Underline", "aria-pressed": isActive ? "true" : "false", children: jsx(UnderlineIcon, { className: "w-4 h-4" }) }, index));
            case "fontSize": {
                const currentOption = getFontSizeOption(formattingState.fontSize);
                const dropdownClassName = themeStyles.dropdownStyle;
                const fontSizeAnimations = createDropdownAnimations(fontSizeIsFlipped);
                const dropdownList = (jsx("div", { className: dropdownClassName, role: "listbox", children: FONT_SIZE_OPTIONS.map((option) => (jsx("button", { className: cn(themeStyles.dropdownItemStyle, option.key === formattingState.fontSize
                            ? "bg-[var(--color-primary-50)] text-[var(--color-primary-900)]"
                            : undefined), "data-active": option.key === formattingState.fontSize ? "true" : "false", onMouseDown: (event) => {
                            event.preventDefault();
                            focusEditor();
                        }, onClick: (event) => {
                            event.preventDefault();
                            event.stopPropagation();
                            handleFontSize(option.key);
                        }, role: "option", "aria-selected": option.key === formattingState.fontSize, children: jsxs("span", { className: "flex items-center justify-between gap-3", children: [jsx("span", { className: "uppercase text-sm font-medium", children: option.label }), jsxs("span", { className: "text-sm text-[var(--color-text-muted)]", children: [option.px, "px"] })] }) }, option.key))) }));
                let renderedDropdown = null;
                if (isFloatingToolbar && isClient) {
                    const triggerWidth = (_a = fontSizeTriggerRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width;
                    const computedWidth = fontSizePortalPosition.width || triggerWidth || undefined;
                    const dropdownStyle = {
                        position: "fixed",
                        top: fontSizePortalPosition.top,
                        left: fontSizePortalPosition.left,
                        zIndex: 1000,
                        ...fontSizePortalCssVars,
                    };
                    if (computedWidth) {
                        dropdownStyle.minWidth = computedWidth;
                        dropdownStyle.width = computedWidth;
                    }
                    renderedDropdown = createPortal(jsx(AnimatePresence, { mode: "wait", children: showFontSizePicker && (jsx(motion.div, { ref: (el) => {
                                fontSizePortalContentRef.current = el;
                            }, style: dropdownStyle, variants: shouldReduceMotion ? undefined : fontSizeAnimations, initial: "initial", animate: fontSizePortalReady ? "visible" : "initial", exit: "exit", children: dropdownList })) }), document.body);
                }
                else {
                    renderedDropdown = showFontSizePicker ? dropdownList : null;
                    if (!showFontSizePicker) {
                        fontSizePortalContentRef.current = null;
                    }
                }
                return (jsxs("div", { className: "relative", "data-tool": "fontSize", children: [jsx(Button, { ref: fontSizeTriggerRef, size: "sm", color: "neutral", variant: "soft", className: cn(themeStyles.toolbarButtonStyle, "px-2 min-w-[3rem] gap-1"), "data-state": isActive ? "active" : "inactive", "data-pressed": isActive ? "true" : "false", onMouseDown: handleMouseDown, onClick: (event) => {
                                event.preventDefault();
                                event.stopPropagation();
                                focusEditor();
                                setShowFontSizePicker((previous) => !previous);
                                setShowColorPicker(false);
                            }, disabled: isDisabled, "aria-label": "Font size", "aria-expanded": showFontSizePicker, "aria-haspopup": "listbox", children: jsx("span", { className: "text-sm font-medium tracking-wide uppercase", children: currentOption.label }) }), toolbarConfig.position === "floating" ? null : renderedDropdown, toolbarConfig.position === "floating" ? renderedDropdown : null] }, index));
            }
            case "textColor":
                {
                    const colorDropdownClassName = cn(themeStyles.dropdownStyle, themeStyles.colorPickerStyle);
                    const colorAnimations = createDropdownAnimations(colorIsFlipped);
                    const colorDropdownList = (jsx("div", { className: cn(colorDropdownClassName, "p-2"), children: colorOptions.map((color) => (jsx("button", { className: themeStyles.colorSwatchStyle, style: { backgroundColor: color.value }, onMouseDown: (event) => {
                                event.preventDefault();
                                focusEditor();
                            }, onClick: (event) => {
                                event.preventDefault();
                                event.stopPropagation();
                                handleTextColor(color.value);
                            }, "aria-label": `Set text color to ${color.label}` }, color.value))) }));
                    let renderedColorDropdown = null;
                    if (isFloatingToolbar && isClient) {
                        const triggerWidth = (_b = colorTriggerRef.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect().width;
                        const computedWidth = colorPortalPosition.width || triggerWidth || undefined;
                        const dropdownStyle = {
                            position: "fixed",
                            top: colorPortalPosition.top,
                            left: colorPortalPosition.left,
                            zIndex: 1000,
                            ...colorPortalCssVars,
                        };
                        if (computedWidth) {
                            dropdownStyle.minWidth = computedWidth;
                            dropdownStyle.width = computedWidth;
                        }
                        renderedColorDropdown = createPortal(jsx(AnimatePresence, { mode: "wait", children: showColorPicker && (jsx(motion.div, { ref: (el) => {
                                    colorPortalContentRef.current = el;
                                }, style: dropdownStyle, variants: shouldReduceMotion ? undefined : colorAnimations, initial: "initial", animate: colorPortalReady ? "visible" : "initial", exit: "exit", children: colorDropdownList })) }), document.body);
                    }
                    else {
                        renderedColorDropdown = showColorPicker ? colorDropdownList : null;
                        if (!showColorPicker) {
                            colorPortalContentRef.current = null;
                        }
                    }
                    return (jsxs("div", { className: "relative", "data-tool": "textColor", children: [jsx(Button, { ref: colorTriggerRef, size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), onMouseDown: handleMouseDown, onClick: (event) => {
                                    event.preventDefault();
                                    event.stopPropagation();
                                    focusEditor();
                                    setShowFontSizePicker(false);
                                    setShowColorPicker((previous) => !previous);
                                }, disabled: isDisabled, "aria-label": "Text Color", "aria-expanded": showColorPicker, children: jsx(PaintBrushIcon, { className: "w-4 h-4" }) }), isFloatingToolbar ? null : renderedColorDropdown, isFloatingToolbar ? renderedColorDropdown : null] }, index));
                }
            case "alignLeft":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", "data-pressed": isActive ? "true" : "false", onMouseDown: handleMouseDown, onClick: (event) => {
                        event.preventDefault();
                        event.stopPropagation();
                        handleAlign("left");
                    }, disabled: isDisabled, "aria-label": "Align Left", "aria-pressed": isActive ? "true" : "false", children: jsx(Bars3BottomLeftIcon, { className: "w-4 h-4" }) }, index));
            case "alignCenter":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", "data-pressed": isActive ? "true" : "false", onMouseDown: handleMouseDown, onClick: (event) => {
                        event.preventDefault();
                        event.stopPropagation();
                        handleAlign("center");
                    }, disabled: isDisabled, "aria-label": "Align Center", "aria-pressed": isActive ? "true" : "false", children: jsx(Bars3Icon, { className: "w-4 h-4" }) }, index));
            case "alignRight":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), "data-state": isActive ? "active" : "inactive", "data-pressed": isActive ? "true" : "false", onMouseDown: handleMouseDown, onClick: (event) => {
                        event.preventDefault();
                        event.stopPropagation();
                        handleAlign("right");
                    }, disabled: isDisabled, "aria-label": "Align Right", "aria-pressed": isActive ? "true" : "false", children: jsx(Bars3BottomRightIcon, { className: "w-4 h-4" }) }, index));
            case "undo":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), onMouseDown: handleMouseDown, onClick: handleUndo, disabled: isDisabled, "aria-label": "Undo", children: jsx(ArrowUturnLeftIcon, { className: "w-4 h-4" }) }, index));
            case "redo":
                return (jsx(Button, { size: "sm", color: "neutral", variant: "soft", iconOnly: true, className: cn(themeStyles.toolbarButtonStyle), onMouseDown: handleMouseDown, onClick: handleRedo, disabled: isDisabled, "aria-label": "Redo", children: jsx(ArrowUturnRightIcon, { className: "w-4 h-4" }) }, index));
            case "separator":
                return jsx("div", { className: themeStyles.separatorStyle }, index);
            default:
                return null;
        }
    };
    const renderToolbar = () => {
        if (!toolbarConfig.show || !toolbarConfig.tools)
            return null;
        const toolbarClass = cn(themeStyles.toolbarStyle, toolbarConfig.className);
        const toolbarContent = (jsx("div", { ref: toolbarRef, className: toolbarClass, children: toolbarConfig.tools.map((tool, index) => renderToolbarTool(tool, index)) }));
        if (toolbarConfig.position === "floating") {
            return (jsx(AnimatePresence, { mode: "wait", children: showToolbar && (jsx(motion.div, { variants: shouldReduceMotion ? undefined : floatingToolbarVariants, initial: "initial", animate: "animate", exit: "exit", className: "bg-white/70 backdrop-blur-sm shadow-2xl rounded-xl border border-[var(--color-border)]  overflow-hidden", style: { position: "absolute", top: toolbarPosition.top, left: toolbarPosition.left, zIndex: 50 }, children: toolbarContent }, "floating-toolbar")) }));
        }
        return toolbarContent;
    };
    return (jsxs("div", { className: cn(themeStyles.wrapperStyle, className), ...props, children: [label && (jsx("div", { className: "mb-1", children: jsx(FormLabel, { htmlFor: editorId, className: labelClassName, state: state, required: required, children: label }) })), jsxs("div", { className: "relative", children: [jsxs("div", { className: cn(themeStyles.containerStyle, themeStyles.states[state], themeStyles.sizes[size]), "data-state": getDataState(), children: [toolbarConfig.position === "top" && renderToolbar(), jsx("div", { ref: (el) => {
                                    if (el) {
                                        editorRef.current = el;
                                        if (typeof ref === "function") {
                                            ref(el);
                                        }
                                        else if (ref) {
                                            ref.current = el;
                                        }
                                    }
                                }, id: editorId, contentEditable: !isDisabled, className: cn(themeStyles.editorStyle), "data-state": getDataState(), style: { minHeight: `${minHeight}px`, maxHeight: maxHeight ? `${maxHeight}px` : undefined }, "data-placeholder": placeholder, onFocus: () => {
                                    setIsFocused(true);
                                    updateFormattingState();
                                }, onBlur: () => {
                                    setIsFocused(false);
                                    if (toolbarConfig.position === "floating") {
                                        setShowToolbar(false);
                                    }
                                    setShowColorPicker(false);
                                    setShowFontSizePicker(false);
                                }, "aria-invalid": isInvalid, "aria-required": required, role: "textbox", "aria-multiline": "true", "aria-label": label || "Rich text editor", suppressContentEditableWarning: true })] }), toolbarConfig.position === "floating" && renderToolbar()] }), helperText && (jsx("div", { className: cn(themeStyles.helperText, helperTextClassName), children: helperText }))] }));
});
RichTextEditor.displayName = "RichTextEditor";

export { RichTextEditor };
