/// <reference types="@dhwaniapp/plugin-sdk" />

(function() {
    const React = window.React;
    const ReactDOM = window.ReactDOM;
    const { Node, ReactNodeViewRenderer, NodeViewWrapper, NodeViewContent, mergeAttributes } = window.DhwaniEditorSDK;

    // 1. Define the React Component for the Badge Node View
    function BadgeComponent(props) {
        const { node, updateAttributes, selected } = props;
        const { backgroundColor = '#ea580c', textColor = '#ffffff', badgeStyle = 'solid' } = node.attrs;
        
        const [coords, setCoords] = React.useState({ top: 0, left: 0 });
        const [selectionTick, setSelectionTick] = React.useState(0);

        // Force component re-render when the editor selection/cursor changes globally
        React.useEffect(() => {
            if (!props.editor) return;
            const handleSelectionUpdate = () => {
                setSelectionTick(t => t + 1);
            };
            props.editor.on('selectionUpdate', handleSelectionUpdate);
            return () => {
                props.editor.off('selectionUpdate', handleSelectionUpdate);
            };
        }, [props.editor]);

        // Detect if editor selection cursor is currently inside this badge text node
        const getPos = props.getPos;
        const selection = props.editor?.state?.selection;
        const nodePos = typeof getPos === 'function' ? getPos() : null;
        
        // Strict boundary check (so cursor at boundary characters is considered outside)
        const isCursorInside = nodePos !== null && selection &&
            selection.from > nodePos && 
            selection.to < nodePos + props.node.nodeSize;

        // Show floating controls ONLY if the node itself is selected or cursor is inside editing
        const isMenuOpen = selected || isCursorInside;

        // Reposition portal above the badge dynamically, catching all scroll events
        React.useEffect(() => {
            if (!isMenuOpen) return;

            const updatePosition = () => {
                const dom = typeof getPos === 'function' ? props.editor.view.nodeDOM(getPos()) : null;
                if (dom) {
                    const rect = dom.getBoundingClientRect();
                    setCoords({
                        top: rect.top - 42,
                        left: rect.left + rect.width / 2
                    });
                }
            };
            
            updatePosition();
            
            // Capture scroll events from any nested scroll containers
            window.addEventListener('scroll', updatePosition, true);
            window.addEventListener('resize', updatePosition);
            return () => {
                window.removeEventListener('scroll', updatePosition, true);
                window.removeEventListener('resize', updatePosition);
            };
        }, [isMenuOpen, selectionTick]);

        // SVGs representing the style modes
        const solidIcon = React.createElement(
            'svg',
            { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 24 24', fill: 'currentColor', className: 'w-3.5 h-3.5' },
            React.createElement('rect', { x: 2, y: 6, width: 20, height: 12, rx: 6 })
        );

        const outlineIcon = React.createElement(
            'svg',
            { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2.5', className: 'w-3.5 h-3.5' },
            React.createElement('rect', { x: 2, y: 6, width: 20, height: 12, rx: 6 })
        );

        const softIcon = React.createElement(
            'svg',
            { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 24 24', fill: 'currentColor', fillOpacity: '0.45', stroke: 'currentColor', strokeWidth: '1.5', className: 'w-3.5 h-3.5' },
            React.createElement('rect', { x: 2, y: 6, width: 20, height: 12, rx: 6 })
        );

        const dashIcon = React.createElement(
            'svg',
            { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2.5', strokeDasharray: '3 2', className: 'w-3.5 h-3.5' },
            React.createElement('rect', { x: 2, y: 6, width: 20, height: 12, rx: 6 })
        );

        const styles = [
            { label: 'Solid', value: 'solid', icon: solidIcon },
            { label: 'Outline', value: 'outline', icon: outlineIcon },
            { label: 'Soft', value: 'soft', icon: softIcon },
            { label: 'Dash', value: 'dash', icon: dashIcon }
        ];

        // Stop propagation to prevent ProseMirror from stealing selection/focus
        const stopPropagation = (e) => {
            e.stopPropagation();
        };

        // Base styles to ensure vertical alignment, inherit editor font size and scale padding proportionally
        let styleObj = {
            display: 'inline-flex',
            alignItems: 'center',
            justifyContent: 'center',
            height: 'auto',
            minHeight: 'fit-content',
            lineHeight: '1.2',
            paddingTop: '0.15em',
            paddingBottom: '0.15em',
            paddingLeft: '0.6em',
            paddingRight: '0.6em',
            borderRadius: '9999px',
            fontFamily: 'var(--editor-font-family, inherit)',
            fontSize: 'var(--editor-font-size, inherit)',
            fontWeight: 'var(--editor-font-weight, 600)',
            verticalAlign: 'middle',
            borderWidth: '1px'
        };

        let activeClasses = 'badge';

        // Apply styles based on badgeStyle selection using custom color picker values
        if (badgeStyle === 'solid') {
            styleObj.backgroundColor = backgroundColor;
            styleObj.color = textColor;
            styleObj.borderColor = backgroundColor;
        } else if (badgeStyle === 'outline') {
            activeClasses += ' badge-outline';
            styleObj.backgroundColor = 'transparent';
            styleObj.color = textColor;
            styleObj.borderColor = textColor;
        } else if (badgeStyle === 'soft') {
            activeClasses += ' badge-soft';
            styleObj.backgroundColor = `color-mix(in srgb, ${backgroundColor} 15%, transparent)`;
            // If text color is white, automatically fallback to background color for legibility in soft style
            styleObj.color = textColor.toLowerCase() === '#ffffff' ? backgroundColor : textColor;
            styleObj.borderColor = 'transparent';
        } else if (badgeStyle === 'dash') {
            activeClasses += ' badge-dash';
            styleObj.borderStyle = 'dashed';
            styleObj.backgroundColor = 'transparent';
            styleObj.color = textColor;
            styleObj.borderColor = textColor;
        }

        return React.createElement(
            NodeViewWrapper,
            {
                as: 'span',
                className: 'relative inline-block align-middle mx-1 group/badge-wrap',
                style: {
                    whiteSpace: 'nowrap'
                }
            },
            // Scoped styles for the custom HTML color picker inputs
            React.createElement('style', null, `
                .badge-color-picker-input {
                    -webkit-appearance: none;
                    appearance: none;
                    border: none;
                    width: 20px;
                    height: 20px;
                    border-radius: 50%;
                    cursor: pointer;
                    padding: 0;
                    background: none;
                    outline: none;
                    box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
                    transition: transform 0.1s ease;
                }
                .badge-color-picker-input:hover {
                    transform: scale(1.1);
                }
                .badge-color-picker-input::-webkit-color-swatch-wrapper {
                    padding: 0;
                }
                .badge-color-picker-input::-webkit-color-swatch {
                    border: 1px solid var(--color-base-300, #d1d5db);
                    border-radius: 50%;
                }
            `),
            // The actual Badge editable text container
            React.createElement(
                NodeViewContent,
                {
                    as: 'span',
                    className: `${activeClasses} cursor-text px-2 font-semibold transition-all hover:opacity-90`,
                    style: styleObj
                }
            ),
            // Render toolbar using React Portal into document.body to prevent clipping by parent tables
            isMenuOpen && ReactDOM.createPortal(
                React.createElement(
                    'span',
                    {
                        className: 'flex items-center gap-2 bg-base-100 border border-base-300 rounded-full px-2.5 py-1.5 shadow-lg text-base-content select-none',
                        style: {
                            position: 'fixed',
                            left: `${coords.left}px`,
                            top: `${coords.top}px`,
                            transform: 'translateX(-50%)',
                            zIndex: 99999,
                            pointerEvents: 'auto',
                            fontFamily: 'sans-serif'
                        },
                        contentEditable: false,
                        onMouseDown: stopPropagation,
                        onClick: stopPropagation
                    },
                    // Color Pickers Section (grouped tightly)
                    React.createElement(
                        'div',
                        { className: 'flex items-center gap-2' },
                        React.createElement(
                            'div',
                            { className: 'flex items-center gap-1', title: 'Background Color' },
                            React.createElement('input', {
                                type: 'color',
                                value: backgroundColor,
                                className: 'badge-color-picker-input',
                                onChange: (e) => updateAttributes({ backgroundColor: e.target.value })
                            }),
                            React.createElement('span', { className: 'text-[9px] font-bold opacity-60' }, 'BG')
                        ),
                        React.createElement(
                            'div',
                            { className: 'flex items-center gap-1', title: 'Text & Outline Color' },
                            React.createElement('input', {
                                type: 'color',
                                value: textColor,
                                className: 'badge-color-picker-input',
                                onChange: (e) => updateAttributes({ textColor: e.target.value })
                            }),
                            React.createElement('span', { className: 'text-[9px] font-bold opacity-60' }, 'TXT')
                        )
                    ),
                    // Divider
                    React.createElement('span', { className: 'w-[1px] h-4 bg-base-300' }),
                    // Styles Selector (SVG Icons)
                    React.createElement(
                        'div',
                        { className: 'flex items-center gap-0.5' },
                        styles.map((s) => {
                            const isCurrent = badgeStyle === s.value;
                            return React.createElement(
                                'button',
                                {
                                    key: s.value,
                                    title: `${s.label} Style`,
                                    className: `btn btn-xs btn-circle border-0 ${isCurrent ? 'btn-active btn-neutral text-neutral-content' : 'btn-ghost text-base-content/70'}`,
                                    style: { width: '22px', height: '22px', minHeight: '0' },
                                    onClick: () => updateAttributes({ badgeStyle: s.value })
                                },
                                s.icon
                            );
                        })
                    )
                ),
                document.body
            )
        );
    }

    // 2. Define the Tiptap Node Configuration for inline badges
    const BadgeNode = Node.create({
        name: 'badge',
        group: 'inline',
        inline: true,
        content: 'text*',
        defining: true,

        addAttributes() {
            return {
                backgroundColor: {
                    default: '#ea580c',
                    parseHTML: element => element.getAttribute('data-badge-bg') || '#ea580c',
                    renderHTML: attributes => ({ 'data-badge-bg': attributes.backgroundColor })
                },
                textColor: {
                    default: '#ffffff',
                    parseHTML: element => element.getAttribute('data-badge-text') || '#ffffff',
                    renderHTML: attributes => ({ 'data-badge-text': attributes.textColor })
                },
                badgeStyle: {
                    default: 'solid',
                    parseHTML: element => element.getAttribute('data-badge-style') || 'solid',
                    renderHTML: attributes => ({ 'data-badge-style': attributes.badgeStyle })
                }
            };
        },

        parseHTML() {
            return [{
                tag: 'span[data-type="badge"]'
            }];
        },

        renderHTML({ HTMLAttributes }) {
            return [
                'span',
                mergeAttributes(HTMLAttributes, { 'data-type': 'badge' }),
                0
            ];
        },

        addNodeView() {
            return ReactNodeViewRenderer(BadgeComponent);
        }
    });

    // 3. Register the extension and slash command
    window.Dhwani.registerPageExtension({
        name: 'badge',
        tiptapExtension: BadgeNode,
        slashCommand: {
            title: 'Badge',
            description: 'Insert an editable badge',
            icon: `<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="w-5 h-5 text-accent">
              <rect x="2" y="5" width="20" height="14" rx="7" stroke-width="3" />
              <rect x="6" y="10.5" width="12" height="3" rx="1.5" fill="currentColor" stroke="none" />
            </svg>`,
            command: (editor) => {
                editor
                    .chain()
                    .focus()
                    .insertContent({
                        type: 'badge',
                        attrs: { backgroundColor: '#ea580c', textColor: '#ffffff', badgeStyle: 'solid' },
                        content: [{ type: 'text', text: 'Badge' }]
                    })
                    .run();
            }
        }
    });

    console.log("[DhwaniBadgePlugin] Loaded successfully!");
})();
