import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { Global } from "@emotion/react";
import { CanvasIcon } from "../../index.js";
import { NodeResizeControl, useReactFlow } from "../../xyflow/react.js";
import { AnimatePresence } from "motion/react";
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import react_markdown from "react-markdown";
import remark_breaks from "remark-breaks";
import remark_gfm from "remark-gfm";
import { GRID_SPACING } from "../../constants.js";
import { NodeViewportOverlay } from "../NodeViewportOverlay.js";
import { NodeToolbar } from "../Toolbar/index.js";
import { FormattingToolbar } from "./FormattingToolbar.js";
import { activeFormatsEqual, continueListOnEnter, detectActiveFormats } from "./markdown-formatting/index.js";
import { BottomCornerIndicators, ColorOption, ColorPickerPanel, RESIZE_CONTROL_Z_INDEX, ResizeHandle, StickyNoteContainer, StickyNoteMarkdown, StickyNoteTextArea, StickyNoteWrapper, TopCornerIndicators, stickyNoteGlobalStyles } from "./StickyNoteNode.styles.js";
import { STICKY_NOTE_COLORS, withAlpha } from "./StickyNoteNode.types.js";
import { preserveNewlines } from "./StickyNoteNode.utils.js";
import { useMarkdownShortcuts } from "./useMarkdownShortcuts.js";
import { useScrollCapture } from "./useScrollCapture.js";
const minWidth = 8 * GRID_SPACING;
const minHeight = 8 * GRID_SPACING;
const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = 'Add text', renderPlaceholderOnSelect = false, readOnly = false, onContentChange, onColorChange, onResize })=>{
    const { updateNodeData, deleteElements } = useReactFlow();
    const [isEditing, setIsEditing] = useState(!readOnly && (data.autoFocus ?? false));
    const [isResizing, setIsResizing] = useState(false);
    const [isColorPickerOpen, setIsColorPickerOpen] = useState(false);
    const [localContent, setLocalContent] = useState(data.content || '');
    const textAreaRef = useRef(null);
    const { ref: markdownRef, scrollCaptureProps } = useScrollCapture();
    const colorButtonRef = useRef(null);
    const [activeFormats, setActiveFormats] = useState({
        bold: false,
        italic: false,
        strikethrough: false,
        bulletList: false,
        numberedList: false
    });
    const colorKey = data.color || 'yellow';
    const color = STICKY_NOTE_COLORS[colorKey] ?? STICKY_NOTE_COLORS.yellow;
    const colorWithAlpha = withAlpha(color);
    useEffect(()=>{
        setLocalContent(data.content || '');
    }, [
        data.content
    ]);
    useEffect(()=>{
        if (isEditing && textAreaRef.current) {
            textAreaRef.current.focus();
            textAreaRef.current.select();
        }
        if (!readOnly && data.autoFocus) updateNodeData(id, {
            autoFocus: false
        });
    }, [
        isEditing,
        data.autoFocus,
        id,
        updateNodeData,
        readOnly
    ]);
    useEffect(()=>{
        if (!selected || isResizing) setIsColorPickerOpen(false);
    }, [
        selected,
        isResizing
    ]);
    useEffect(()=>{
        if (readOnly) {
            setIsEditing(false);
            setLocalContent(data.content || '');
        }
    }, [
        readOnly,
        data.content
    ]);
    const handleDoubleClick = useCallback(()=>{
        if (readOnly || isEditing) return;
        setIsEditing(true);
        setTimeout(()=>{
            if (textAreaRef.current) {
                textAreaRef.current.focus();
                textAreaRef.current.select();
            }
        }, 0);
    }, [
        isEditing,
        readOnly
    ]);
    const handleBlur = useCallback(()=>{
        setIsEditing(false);
        if (readOnly) return;
        if (localContent !== data.content) {
            onContentChange?.(localContent);
            updateNodeData(id, {
                content: localContent
            });
        }
    }, [
        id,
        localContent,
        data.content,
        updateNodeData,
        onContentChange,
        readOnly
    ]);
    const handleChange = useCallback((e)=>{
        setLocalContent(e.target.value);
    }, []);
    const handleFormat = useCallback((result)=>{
        setLocalContent(result.value);
        setActiveFormats(detectActiveFormats(result));
        requestAnimationFrame(()=>{
            if (textAreaRef.current) {
                textAreaRef.current.selectionStart = result.selectionStart;
                textAreaRef.current.selectionEnd = result.selectionEnd;
            }
        });
    }, []);
    const updateActiveFormats = useCallback(()=>{
        if (!textAreaRef.current) return;
        const next = detectActiveFormats({
            value: textAreaRef.current.value,
            selectionStart: textAreaRef.current.selectionStart,
            selectionEnd: textAreaRef.current.selectionEnd
        });
        setActiveFormats((prev)=>activeFormatsEqual(prev, next) ? prev : next);
    }, []);
    const shortcutKeyDown = useMarkdownShortcuts(textAreaRef, handleFormat);
    const handleKeyDown = useCallback((e)=>{
        if ('Escape' === e.key) {
            setIsEditing(false);
            setLocalContent(data.content || '');
            textAreaRef.current?.blur();
            return;
        }
        if ('Enter' === e.key && !e.shiftKey && !e.metaKey && !e.ctrlKey) {
            const textarea = textAreaRef.current;
            if (textarea) {
                const result = continueListOnEnter({
                    value: textarea.value,
                    selectionStart: textarea.selectionStart,
                    selectionEnd: textarea.selectionEnd
                });
                if (result) {
                    e.preventDefault();
                    handleFormat(result);
                }
            }
            return;
        }
        shortcutKeyDown(e);
    }, [
        data.content,
        shortcutKeyDown,
        handleFormat
    ]);
    const handleResizeStart = useCallback(()=>{
        setIsResizing(true);
    }, []);
    const handleResizeEnd = useCallback((_event, params)=>{
        setIsResizing(false);
        onResize?.(params.width, params.height);
    }, [
        onResize
    ]);
    const handleColorChange = useCallback((newColor)=>{
        onColorChange?.(newColor);
        updateNodeData(id, {
            color: newColor
        });
        setIsColorPickerOpen(false);
    }, [
        id,
        updateNodeData,
        onColorChange
    ]);
    const handleToggleColorPicker = useCallback(()=>{
        setIsColorPickerOpen((prev)=>!prev);
    }, []);
    const handleEditClick = useCallback(()=>{
        if (readOnly) return;
        setIsEditing(true);
        setTimeout(()=>{
            if (textAreaRef.current) {
                textAreaRef.current.focus();
                textAreaRef.current.select();
            }
        }, 0);
    }, [
        readOnly
    ]);
    const handleDelete = useCallback(()=>{
        deleteElements({
            nodes: [
                {
                    id
                }
            ]
        });
    }, [
        id,
        deleteElements
    ]);
    const markdownComponents = useMemo(()=>({
            a: ({ href, children, ...props })=>/*#__PURE__*/ jsx("a", {
                    ...props,
                    href: href,
                    target: "_blank",
                    rel: "noopener noreferrer",
                    onClick: (e)=>{
                        e.stopPropagation();
                    },
                    onDoubleClick: (e)=>{
                        e.stopPropagation();
                    },
                    children: children
                })
        }), []);
    const toolbarConfig = useMemo(()=>{
        const actions = [
            {
                id: 'delete',
                icon: /*#__PURE__*/ jsx(CanvasIcon, {
                    icon: "trash",
                    size: 14
                }),
                label: 'Delete',
                onAction: handleDelete
            },
            {
                id: 'edit',
                icon: /*#__PURE__*/ jsx(CanvasIcon, {
                    icon: "pencil",
                    size: 14
                }),
                label: 'Edit',
                onAction: handleEditClick
            },
            {
                id: 'separator'
            },
            {
                id: 'color',
                icon: /*#__PURE__*/ jsx("div", {
                    ref: colorButtonRef,
                    style: {
                        width: '16px',
                        height: '16px',
                        borderRadius: '50%',
                        backgroundColor: color,
                        border: '1px solid transparent'
                    }
                }),
                label: 'Color',
                onAction: handleToggleColorPicker
            }
        ];
        return {
            actions,
            overflowActions: [],
            overflowLabel: '',
            position: 'top',
            align: 'center'
        };
    }, [
        handleEditClick,
        handleToggleColorPicker,
        color,
        handleDelete
    ]);
    return /*#__PURE__*/ jsxs(Fragment, {
        children: [
            /*#__PURE__*/ jsx(Global, {
                styles: stickyNoteGlobalStyles
            }),
            /*#__PURE__*/ jsxs(StickyNoteWrapper, {
                "data-sticky-note": true,
                children: [
                    !readOnly && /*#__PURE__*/ jsxs(Fragment, {
                        children: [
                            /*#__PURE__*/ jsx(NodeResizeControl, {
                                style: {
                                    background: 'transparent',
                                    border: 'none',
                                    zIndex: RESIZE_CONTROL_Z_INDEX
                                },
                                position: "top-left",
                                minWidth: minWidth,
                                minHeight: minHeight,
                                onResizeStart: handleResizeStart,
                                onResizeEnd: handleResizeEnd,
                                children: /*#__PURE__*/ jsx(ResizeHandle, {
                                    selected: selected,
                                    cursor: "nwse-resize"
                                })
                            }),
                            /*#__PURE__*/ jsx(NodeResizeControl, {
                                style: {
                                    background: 'transparent',
                                    border: 'none',
                                    zIndex: RESIZE_CONTROL_Z_INDEX
                                },
                                position: "top-right",
                                minWidth: minWidth,
                                minHeight: minHeight,
                                onResizeStart: handleResizeStart,
                                onResizeEnd: handleResizeEnd,
                                children: /*#__PURE__*/ jsx(ResizeHandle, {
                                    selected: selected,
                                    cursor: "nesw-resize"
                                })
                            }),
                            /*#__PURE__*/ jsx(NodeResizeControl, {
                                style: {
                                    background: 'transparent',
                                    border: 'none',
                                    zIndex: RESIZE_CONTROL_Z_INDEX
                                },
                                position: "bottom-left",
                                minWidth: minWidth,
                                minHeight: minHeight,
                                onResizeStart: handleResizeStart,
                                onResizeEnd: handleResizeEnd,
                                children: /*#__PURE__*/ jsx(ResizeHandle, {
                                    selected: selected,
                                    cursor: "nesw-resize"
                                })
                            }),
                            /*#__PURE__*/ jsx(NodeResizeControl, {
                                style: {
                                    background: 'transparent',
                                    border: 'none',
                                    zIndex: RESIZE_CONTROL_Z_INDEX
                                },
                                position: "bottom-right",
                                minWidth: minWidth,
                                minHeight: minHeight,
                                onResizeStart: handleResizeStart,
                                onResizeEnd: handleResizeEnd,
                                children: /*#__PURE__*/ jsx(ResizeHandle, {
                                    selected: selected,
                                    cursor: "nwse-resize"
                                })
                            })
                        ]
                    }),
                    /*#__PURE__*/ jsxs(StickyNoteContainer, {
                        backgroundColor: colorWithAlpha,
                        borderColor: color,
                        isEditing: isEditing,
                        selected: selected,
                        isReadOnly: readOnly,
                        onDoubleClick: handleDoubleClick,
                        children: [
                            /*#__PURE__*/ jsx(TopCornerIndicators, {
                                visible: selected && !readOnly
                            }),
                            /*#__PURE__*/ jsx(BottomCornerIndicators, {
                                visible: selected && !readOnly
                            }),
                            isEditing ? /*#__PURE__*/ jsxs(Fragment, {
                                children: [
                                    /*#__PURE__*/ jsx(FormattingToolbar, {
                                        textAreaRef: textAreaRef,
                                        borderColor: color,
                                        activeFormats: activeFormats,
                                        onFormat: handleFormat
                                    }),
                                    /*#__PURE__*/ jsx(StickyNoteTextArea, {
                                        ref: textAreaRef,
                                        value: localContent,
                                        onChange: handleChange,
                                        onBlur: handleBlur,
                                        onKeyDown: handleKeyDown,
                                        onSelect: updateActiveFormats,
                                        onKeyUp: updateActiveFormats,
                                        placeholder: placeholder,
                                        isEditing: isEditing,
                                        className: "nodrag nowheel"
                                    })
                                ]
                            }) : /*#__PURE__*/ jsx(StickyNoteMarkdown, {
                                ref: markdownRef,
                                ...scrollCaptureProps,
                                children: localContent ? /*#__PURE__*/ jsx(react_markdown, {
                                    remarkPlugins: [
                                        remark_gfm,
                                        remark_breaks
                                    ],
                                    components: markdownComponents,
                                    children: preserveNewlines(localContent)
                                }) : renderPlaceholderOnSelect && selected && /*#__PURE__*/ jsx(react_markdown, {
                                    remarkPlugins: [
                                        remark_gfm,
                                        remark_breaks
                                    ],
                                    components: markdownComponents,
                                    children: placeholder
                                })
                            })
                        ]
                    }),
                    !readOnly && selected && !dragging && !isResizing && /*#__PURE__*/ jsx(NodeToolbar, {
                        nodeId: id,
                        config: toolbarConfig,
                        expanded: true,
                        portalToNodeOverlay: true
                    }),
                    !readOnly && selected && !dragging && !isResizing && /*#__PURE__*/ jsx(NodeViewportOverlay, {
                        nodeId: id,
                        layer: "nodeToolbar",
                        children: /*#__PURE__*/ jsx(AnimatePresence, {
                            children: isColorPickerOpen && /*#__PURE__*/ jsx("div", {
                                className: "nodrag nopan nowheel",
                                style: {
                                    position: 'absolute',
                                    top: -40,
                                    left: '50%',
                                    transform: 'translateX(40px)',
                                    zIndex: 1000,
                                    pointerEvents: 'auto'
                                },
                                onMouseDown: (e)=>{
                                    e.preventDefault();
                                    e.stopPropagation();
                                },
                                onClick: (e)=>e.stopPropagation(),
                                children: /*#__PURE__*/ jsx(ColorPickerPanel, {
                                    initial: {
                                        opacity: 0,
                                        y: 10
                                    },
                                    animate: {
                                        opacity: 1,
                                        y: 0
                                    },
                                    exit: {
                                        opacity: 0,
                                        y: 10
                                    },
                                    transition: {
                                        duration: 0.15,
                                        ease: 'easeOut'
                                    },
                                    children: Object.keys(STICKY_NOTE_COLORS).map((stickyColorKey)=>{
                                        const colorName = stickyColorKey;
                                        return /*#__PURE__*/ jsx(ColorOption, {
                                            type: "button",
                                            color: STICKY_NOTE_COLORS[colorName],
                                            isSelected: colorKey === colorName,
                                            onClick: ()=>handleColorChange(colorName),
                                            title: colorName.charAt(0).toUpperCase() + colorName.slice(1)
                                        }, stickyColorKey);
                                    })
                                })
                            })
                        })
                    })
                ]
            })
        ]
    });
};
const StickyNoteNode = /*#__PURE__*/ memo(StickyNoteNodeComponent);
export { StickyNoteNode };
