import { CSS } from './config.js';
import { eventBus, Events } from './events.js';

/**
 * Centralized window registry
 * Manages window visibility and positioning
 */
class WindowRegistry {
    constructor() {
        this.windows = new Map();
    }

    /**
     * Registers a window in the registry
     * @param {string} name - Unique window name
     * @param {Window} window - Window instance
     */
    register(name, window) {
        this.windows.set(name, window);
    }

    /**
     * Gets a window by its name
     * @param {string} name - Window name
     * @returns {Window|undefined}
     */
    get(name) {
        return this.windows.get(name);
    }

    /**
     * Returns all visible windows
     * @returns {Window[]}
     */
    getVisible() {
        return Array.from(this.windows.values()).filter(w => w.isVisible());
    }

    /**
     * Reorganizes visible windows
     */
    reorganize() {
        const visible = this.getVisible();

        if (visible.length === 0) return;

        if (visible.length === 1) {
            visible[0].setPosition('center');
        } else if (visible.length === 2) {
            visible[0].setPosition('left');
            visible[1].setPosition('right');
        } else {
            visible.forEach(w => w.setPosition('center'));
        }
    }

    /**
     * Shows a window and reorganizes
     * @param {string} name - Window name
     */
    show(name) {
        const window = this.get(name);
        if (window) {
            window.show();
        }
    }

    /**
     * Hides a window and reorganizes
     * @param {string} name - Window name
     */
    hide(name) {
        const window = this.get(name);
        if (window) {
            window.hide();
        }
    }

    /**
     * Toggles window visibility
     * @param {string} name - Window name
     */
    toggle(name) {
        const window = this.get(name);
        if (window) {
            window.toggle();
        }
    }
}

// Singleton registry instance
export const windowRegistry = new WindowRegistry();

/**
 * Base class for all windows
 * Uses CSS classes instead of inline styles
 */
export class Window {
    /**
     * @param {Object} options - Configuration options
     * @param {string} options.name - Unique name for the registry
     * @param {string} options.title - Title displayed in the header
     * @param {string[]} [options.cssClasses] - Additional CSS classes
     */
    constructor({ name, title, cssClasses = [] }) {
        this.name = name;

        // Create main container
        this.element = document.createElement('div');
        this.element.className = [CSS.WINDOW, ...cssClasses].join(' ');

        // Header
        this.header = document.createElement('div');
        this.header.className = CSS.WINDOW_HEADER;

        this.titleElement = document.createElement('span');
        this.titleElement.className = CSS.WINDOW_TITLE;
        this.titleElement.textContent = title;

        this.closeBtn = document.createElement('button');
        this.closeBtn.className = CSS.WINDOW_CLOSE;
        this.closeBtn.textContent = '✖';
        this.closeBtn.setAttribute('aria-label', 'Close');
        this.closeBtn.addEventListener('click', () => this.hide());

        this.header.append(this.titleElement, this.closeBtn);

        // Body
        this.body = document.createElement('div');
        this.body.className = CSS.WINDOW_BODY;

        // Assembly
        this.element.append(this.header, this.body);
        document.body.appendChild(this.element);

        // Register in the registry
        windowRegistry.register(name, this);
    }

    /**
     * Checks if the window is visible
     * @returns {boolean}
     */
    isVisible() {
        return this.element.classList.contains(CSS.WINDOW_VISIBLE);
    }

    /**
     * Sets the window position
     * @param {'center'|'left'|'right'} position
     */
    setPosition(position) {
        this.element.classList.remove('window--left', 'window--right');

        if (position === 'left') {
            this.element.classList.add('window--left');
        } else if (position === 'right') {
            this.element.classList.add('window--right');
        }
    }

    /**
     * Shows the window
     */
    show() {
        const wasHidden = !this.isVisible();
        this.element.classList.add(CSS.WINDOW_VISIBLE);

        if (wasHidden) {
            windowRegistry.reorganize();
            eventBus.emit(Events.WINDOW_OPENED, { name: this.name });
        }
    }

    /**
     * Hides the window
     */
    hide() {
        const wasVisible = this.isVisible();
        this.element.classList.remove(CSS.WINDOW_VISIBLE);

        if (wasVisible) {
            windowRegistry.reorganize();
            eventBus.emit(Events.WINDOW_CLOSED, { name: this.name });
        }
    }

    /**
     * Toggles visibility
     */
    toggle() {
        if (this.isVisible()) {
            this.hide();
        } else {
            this.show();
        }
    }

    /**
     * Updates the window title
     * @param {string} title
     */
    setTitle(title) {
        this.titleElement.textContent = title;
    }

    /**
     * Creates an element with CSS classes
     * @param {string} tag - HTML tag
     * @param {string|string[]} classes - CSS classes
     * @param {Object} [attrs] - Additional attributes
     * @returns {HTMLElement}
     */
    createElement(tag, classes, attrs = {}) {
        const element = document.createElement(tag);
        const classList = Array.isArray(classes) ? classes : [classes];
        element.className = classList.filter(Boolean).join(' ');

        Object.entries(attrs).forEach(([key, value]) => {
            if (key === 'text') {
                element.textContent = value;
            } else if (key === 'html') {
                element.innerHTML = value;
            } else {
                element.setAttribute(key, value);
            }
        });

        return element;
    }

    NotficationContainer()
	{
		if (document.getElementById('notification-container')) return;

		const container = this.createElement('div');
		container.id = 'notification-container';
		Object.assign(container.style, {
			position: 'fixed',
			top: '20px',
			right: '20px',
			zIndex: 1000,
			display: 'flex',
			flexDirection: 'column',
			gap: '10px'
		});
		document.body.appendChild(container);
	}

	showNotification(message, color) {
        this.NotficationContainer();
		const container = document.getElementById('notification-container');
		if (!container) return;

		const notification = document.createElement('div');
		notification.textContent = message;
		Object.assign(notification.style, {
			backgroundColor: color,
			color: 'white',
			padding: '10px 20px',
			borderRadius: '5px',
			boxShadow: '0 2px 6px rgba(0,0,0,0.3)',
			opacity: '0',
			transform: 'translateY(-8px)',
            transition: 'opacity 0.5s ease, transform 0.5s ease'
		});

		container.appendChild(notification);

		requestAnimationFrame(() => {
			notification.style.opacity = '1';
			notification.style.transform = 'translateY(0)';
		});

		setTimeout(() => {
			notification.style.opacity = '0';
			notification.style.transform = 'translateY(-8px)';
			setTimeout(() => notification.remove(), 500);
		}, 2200);
	}
}

// Export old class name for compatibility (alias)
export { Window as fenetre };
