import {useEvent} from "../../../core/useEvent";

export class Dialog {
    constructor({content = '', className = '', onClose = null} = {}) {
        this.onClose = onClose;
        this.className = className;
        this.isOpenState = false;
        this.dialog = document.createElement('dialog');
        this.dialog.className = className;
        this.eventCleanup = []; // Track cleanup functions
        
        this.updateContent(content);
        this.bindEvents();
    }

    /**
     * Bind event handlers to the dialog
     */
    bindEvents() {
        // Clean up any existing event listeners first
        this.cleanupEvents();
        
        // Store references to bound event handlers for cleanup
        this.clickHandler = (e) => {
            const isOutside = !e.target.closest('.' + this.className + '-content');
            if (isOutside) this.close();
        };

        this.cancelHandler = (e) => {
            e.preventDefault();
            this.close();
        };
        
        // Use direct event listeners instead of useEvent to avoid module-based cleanup issues
        this.dialog.addEventListener('click', this.clickHandler);
        this.dialog.addEventListener('cancel', this.cancelHandler);
        
        // Store cleanup functions
        this.eventCleanup = [
            () => this.dialog.removeEventListener('click', this.clickHandler),
            () => this.dialog.removeEventListener('cancel', this.cancelHandler)
        ];
    }

    /**
     * Clean up existing event listeners
     */
    cleanupEvents() {
        this.eventCleanup.forEach(cleanup => cleanup());
        this.eventCleanup = [];
    }

    /**
     * Update the content of the dialog without recreating it
     * @param {string} content - New HTML content
     */
    updateContent(content) {
        this.dialog.innerHTML = `
            <form method="dialog" class="${this.className}-content">
                ${content}
                <button class="${this.className}-close" value="close">×</button>
            </form>
        `;
        
        // No need to rebind events - they're attached to the dialog element itself
        // which doesn't get replaced by innerHTML
    }

    open() {
        // Always ensure dialog is in DOM
        if (!this.dialog.parentElement) {
            document.body.appendChild(this.dialog);
        }
        
        // Force close if somehow already open
        if (this.dialog.hasAttribute('open') || this.dialog.open) {
            this.dialog.close?.() || this.dialog.removeAttribute('open');
        }
        
        // Now open fresh
        this.dialog.showModal?.() || this.dialog.setAttribute('open', '');
        document.documentElement.dataset[`${this.dialog.className}Open`] = 'true';
        this.isOpenState = true;
    }

    close() {
        if (this.isOpenState) {
            this.dialog.close?.() || this.dialog.removeAttribute('open');
            delete document.documentElement.dataset[`${this.dialog.className}Open`];
            this.isOpenState = false;
            
            // Keep dialog in DOM for reuse, just hide it
            // Don't remove from DOM to enable singleton pattern
            
            this.onClose?.();
        }
    }

    /**
     * Check if dialog is currently open (checks both state and DOM)
     * @returns {boolean}
     */
    isOpen() {
        // Check both our internal state and the actual DOM state
        const domIsOpen = this.dialog && (this.dialog.hasAttribute('open') || this.dialog.open);
        
        // Sync our internal state with DOM reality
        if (domIsOpen !== this.isOpenState) {
            this.isOpenState = domIsOpen;
        }
        
        return this.isOpenState;
    }

    /**
     * Destroy the dialog completely (for cleanup)
     */
    destroy() {
        if (this.isOpenState) {
            this.close();
        }
        this.cleanupEvents();
        if (this.dialog.parentElement) {
            this.dialog.remove();
        }
    }
}
