/**
 * ThrillWiki Alpine.js Global Stores
 *
 * This file is the single source of truth for all Alpine.js global stores.
 * Stores provide shared state management across components.
 *
 * Available Stores:
 * - $store.auth: User authentication state
 * - $store.theme: Theme (dark/light mode) management
 * - $store.search: Global search state
 * - $store.toast: Toast notification system
 * - $store.ui: UI state (sidebar, modals, etc.)
 *
 * Usage in templates:
 *   <button @click="$store.theme.toggle()">Toggle Theme</button>
 *   <span x-text="$store.auth.user?.username"></span>
 *   <button @click="$store.toast.success('Saved!')">Save</button>
 */

document.addEventListener('alpine:init', () => {
    // =========================================================================
    // Authentication Store
    // =========================================================================

    Alpine.store('auth', {
        user: null,
        isAuthenticated: false,
        permissions: [],

        /**
         * Initialize auth state from server-rendered data
         * The server should render window.__AUTH_USER__ and window.__AUTH_PERMISSIONS__
         */
        init() {
            if (window.__AUTH_USER__) {
                this.user = window.__AUTH_USER__;
                this.isAuthenticated = true;
                this.permissions = window.__AUTH_PERMISSIONS__ || [];
            }
        },

        /**
         * Check if user has a specific permission
         * @param {string} permission - Permission string to check
         * @returns {boolean}
         */
        hasPermission(permission) {
            return this.permissions.includes(permission);
        },

        /**
         * Check if user has any of the specified permissions
         * @param {string[]} permissions - Array of permission strings
         * @returns {boolean}
         */
        hasAnyPermission(permissions) {
            return permissions.some(p => this.permissions.includes(p));
        },

        /**
         * Update user data (after login/profile update)
         * @param {Object} userData - User data object
         */
        setUser(userData) {
            this.user = userData;
            this.isAuthenticated = !!userData;
        },

        /**
         * Clear auth state (on logout)
         */
        logout() {
            this.user = null;
            this.isAuthenticated = false;
            this.permissions = [];
        }
    });

    // =========================================================================
    // Theme Store
    // =========================================================================

    Alpine.store('theme', {
        isDark: false,

        /**
         * Initialize theme from localStorage or system preference
         */
        init() {
            const savedTheme = localStorage.getItem('theme');
            const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

            this.isDark = savedTheme === 'dark' || (!savedTheme && prefersDark);
            this.apply();

            // Watch for system theme changes
            window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
                if (!localStorage.getItem('theme')) {
                    this.isDark = e.matches;
                    this.apply();
                }
            });
        },

        /**
         * Toggle between dark and light mode
         */
        toggle() {
            this.isDark = !this.isDark;
            this.apply();
        },

        /**
         * Set a specific theme
         * @param {string} mode - 'dark', 'light', or 'system'
         */
        setMode(mode) {
            if (mode === 'system') {
                localStorage.removeItem('theme');
                this.isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
            } else {
                this.isDark = mode === 'dark';
                localStorage.setItem('theme', this.isDark ? 'dark' : 'light');
            }
            this.apply();
        },

        /**
         * Apply the current theme to the document
         */
        apply() {
            document.documentElement.classList.toggle('dark', this.isDark);
            localStorage.setItem('theme', this.isDark ? 'dark' : 'light');
        }
    });

    // =========================================================================
    // Search Store
    // =========================================================================

    Alpine.store('search', {
        query: '',
        results: [],
        isOpen: false,
        isLoading: false,
        filters: {},

        /**
         * Toggle the search modal/dropdown
         */
        toggle() {
            this.isOpen = !this.isOpen;
            if (this.isOpen) {
                // Focus search input when opening
                this.$nextTick(() => {
                    const input = document.querySelector('[data-search-input]');
                    if (input) input.focus();
                });
            }
        },

        /**
         * Open the search modal
         */
        open() {
            this.isOpen = true;
        },

        /**
         * Close the search modal
         */
        close() {
            this.isOpen = false;
        },

        /**
         * Clear the search query and results
         */
        clearSearch() {
            this.query = '';
            this.results = [];
        },

        /**
         * Set a filter value
         * @param {string} key - Filter key
         * @param {*} value - Filter value
         */
        setFilter(key, value) {
            this.filters[key] = value;
        },

        /**
         * Clear all filters
         */
        clearFilters() {
            this.filters = {};
        }
    });

    // =========================================================================
    // Toast Store
    // =========================================================================

    Alpine.store('toast', {
        toasts: [],

        /**
         * Show a toast notification
         * @param {string} message - Toast message
         * @param {string} type - Toast type (success, error, warning, info)
         * @param {number} duration - Duration in ms (0 for persistent)
         * @returns {number} - Toast ID for programmatic dismissal
         */
        show(message, type = 'info', duration = 5000) {
            const id = Date.now() + Math.random();
            const toast = {
                id,
                message,
                type,
                visible: true,
                duration
            };

            this.toasts.push(toast);

            if (duration > 0) {
                setTimeout(() => {
                    this.dismiss(id);
                }, duration);
            }

            return id;
        },

        /**
         * Dismiss a toast by ID
         * @param {number} id - Toast ID
         */
        dismiss(id) {
            const toast = this.toasts.find(t => t.id === id);
            if (toast) {
                toast.visible = false;
                // Remove from array after animation
                setTimeout(() => {
                    this.toasts = this.toasts.filter(t => t.id !== id);
                }, 300);
            }
        },

        /**
         * Show a success toast
         * @param {string} message
         * @param {number} duration
         */
        success(message, duration = 5000) {
            return this.show(message, 'success', duration);
        },

        /**
         * Show an error toast
         * @param {string} message
         * @param {number} duration
         */
        error(message, duration = 7000) {
            return this.show(message, 'error', duration);
        },

        /**
         * Show a warning toast
         * @param {string} message
         * @param {number} duration
         */
        warning(message, duration = 6000) {
            return this.show(message, 'warning', duration);
        },

        /**
         * Show an info toast
         * @param {string} message
         * @param {number} duration
         */
        info(message, duration = 5000) {
            return this.show(message, 'info', duration);
        },

        /**
         * Clear all toasts
         */
        clearAll() {
            this.toasts = [];
        }
    });

    // =========================================================================
    // UI State Store
    // =========================================================================

    Alpine.store('ui', {
        sidebarOpen: false,
        modalStack: [],
        activeDropdown: null,

        /**
         * Toggle the sidebar
         */
        toggleSidebar() {
            this.sidebarOpen = !this.sidebarOpen;
            document.body.style.overflow = this.sidebarOpen ? 'hidden' : '';
        },

        /**
         * Open a modal by ID
         * @param {string} id - Modal ID
         */
        openModal(id) {
            if (!this.modalStack.includes(id)) {
                this.modalStack.push(id);
                document.body.style.overflow = 'hidden';
            }
        },

        /**
         * Close a modal by ID
         * @param {string} id - Modal ID
         */
        closeModal(id) {
            this.modalStack = this.modalStack.filter(m => m !== id);
            if (this.modalStack.length === 0) {
                document.body.style.overflow = '';
            }
        },

        /**
         * Close the topmost modal
         */
        closeTopModal() {
            if (this.modalStack.length > 0) {
                this.closeModal(this.modalStack[this.modalStack.length - 1]);
            }
        },

        /**
         * Check if a modal is open
         * @param {string} id - Modal ID
         * @returns {boolean}
         */
        isModalOpen(id) {
            return this.modalStack.includes(id);
        },

        /**
         * Check if any modal is open
         * @returns {boolean}
         */
        hasOpenModal() {
            return this.modalStack.length > 0;
        },

        /**
         * Set the active dropdown (closes others)
         * @param {string|null} id - Dropdown ID or null to close all
         */
        setActiveDropdown(id) {
            this.activeDropdown = id;
        },

        /**
         * Check if a dropdown is active
         * @param {string} id - Dropdown ID
         * @returns {boolean}
         */
        isDropdownActive(id) {
            return this.activeDropdown === id;
        }
    });

    // =========================================================================
    // App Store (General application state)
    // =========================================================================

    Alpine.store('app', {
        loading: false,
        notifications: [],

        /**
         * Set global loading state
         * @param {boolean} state
         */
        setLoading(state) {
            this.loading = state;
        },

        /**
         * Add a notification
         * @param {Object} notification
         */
        addNotification(notification) {
            this.notifications.push({
                id: Date.now(),
                read: false,
                timestamp: new Date(),
                ...notification
            });
        },

        /**
         * Mark a notification as read
         * @param {number} id
         */
        markAsRead(id) {
            const notification = this.notifications.find(n => n.id === id);
            if (notification) {
                notification.read = true;
            }
        },

        /**
         * Mark all notifications as read
         */
        markAllAsRead() {
            this.notifications.forEach(n => n.read = true);
        },

        /**
         * Remove a notification
         * @param {number} id
         */
        removeNotification(id) {
            this.notifications = this.notifications.filter(n => n.id !== id);
        },

        /**
         * Get unread notification count
         * @returns {number}
         */
        get unreadCount() {
            return this.notifications.filter(n => !n.read).length;
        }
    });

    console.log('Alpine.js stores initialized');
});
