/**
 * ThrillWiki Alpine.js Components
 *
 * This file contains Alpine.js component definitions for client-side UI state management.
 * Store definitions are in stores/index.js - this file focuses on reusable data components.
 *
 * Note: Theme, toast, and auth stores are defined in stores/index.js to avoid duplication.
 * Use $store.theme, $store.toast, $store.auth, $store.ui, $store.search for global state.
 */

document.addEventListener('alpine:init', () => {
    // =========================================================================
    // Search Component - Client-side search with debouncing
    // =========================================================================

    Alpine.data('searchComponent', () => ({
        query: '',
        results: [],
        loading: false,
        showResults: false,
        debounceTimer: null,

        init() {
            // Watch for query changes with debouncing
            this.$watch('query', (value) => {
                clearTimeout(this.debounceTimer);
                if (value.length < 2) {
                    this.results = [];
                    this.showResults = false;
                    return;
                }
                this.debounceTimer = setTimeout(() => this.search(), 300);
            });
        },

        async search() {
            if (this.query.length < 2) {
                this.results = [];
                this.showResults = false;
                return;
            }

            this.loading = true;

            try {
                const response = await fetch(`/api/search/?q=${encodeURIComponent(this.query)}`);
                const data = await response.json();
                this.results = data.results || [];
                this.showResults = this.results.length > 0;
            } catch (error) {
                console.error('Search error:', error);
                this.results = [];
                this.showResults = false;
            } finally {
                this.loading = false;
            }
        },

        selectResult(result) {
            window.location.href = result.url;
            this.showResults = false;
            this.query = '';
        },

        clearSearch() {
            this.query = '';
            this.results = [];
            this.showResults = false;
        },

        // Keyboard navigation
        highlightedIndex: -1,

        highlightNext() {
            if (this.highlightedIndex < this.results.length - 1) {
                this.highlightedIndex++;
            }
        },

        highlightPrev() {
            if (this.highlightedIndex > 0) {
                this.highlightedIndex--;
            }
        },

        selectHighlighted() {
            if (this.highlightedIndex >= 0 && this.results[this.highlightedIndex]) {
                this.selectResult(this.results[this.highlightedIndex]);
            }
        }
    }));

    // =========================================================================
    // Browse Menu Component
    // =========================================================================

    Alpine.data('browseMenu', () => ({
        open: false,

        toggle() {
            this.open = !this.open;
        },

        close() {
            this.open = false;
        }
    }));

    // =========================================================================
    // Mobile Menu Component
    // =========================================================================

    Alpine.data('mobileMenu', () => ({
        open: false,

        toggle() {
            this.open = !this.open;
            // Prevent body scroll when menu is open
            document.body.style.overflow = this.open ? 'hidden' : '';
        },

        close() {
            this.open = false;
            document.body.style.overflow = '';
        }
    }));

    // =========================================================================
    // User Menu Component
    // =========================================================================

    Alpine.data('userMenu', () => ({
        open: false,

        toggle() {
            this.open = !this.open;
        },

        close() {
            this.open = false;
        }
    }));

    // =========================================================================
    // Modal Component
    // =========================================================================

    Alpine.data('modal', (initialOpen = false) => ({
        open: initialOpen,

        show() {
            this.open = true;
            document.body.style.overflow = 'hidden';
        },

        hide() {
            this.open = false;
            document.body.style.overflow = '';
        },

        toggle() {
            if (this.open) {
                this.hide();
            } else {
                this.show();
            }
        }
    }));

    // =========================================================================
    // Dropdown Component
    // =========================================================================

    Alpine.data('dropdown', (initialOpen = false) => ({
        open: initialOpen,

        toggle() {
            this.open = !this.open;
        },

        close() {
            this.open = false;
        },

        show() {
            this.open = true;
        }
    }));

    // =========================================================================
    // Tabs Component
    // =========================================================================

    Alpine.data('tabs', (defaultTab = 0) => ({
        activeTab: defaultTab,

        setTab(index) {
            this.activeTab = index;
        },

        isActive(index) {
            return this.activeTab === index;
        }
    }));

    // =========================================================================
    // Accordion Component
    // =========================================================================

    Alpine.data('accordion', (allowMultiple = false) => ({
        openItems: [],

        toggle(index) {
            if (this.isOpen(index)) {
                this.openItems = this.openItems.filter(item => item !== index);
            } else {
                if (allowMultiple) {
                    this.openItems.push(index);
                } else {
                    this.openItems = [index];
                }
            }
        },

        isOpen(index) {
            return this.openItems.includes(index);
        },

        open(index) {
            if (!this.isOpen(index)) {
                if (allowMultiple) {
                    this.openItems.push(index);
                } else {
                    this.openItems = [index];
                }
            }
        },

        close(index) {
            this.openItems = this.openItems.filter(item => item !== index);
        }
    }));

    // =========================================================================
    // Form Component with Validation
    // =========================================================================

    Alpine.data('form', (initialData = {}) => ({
        data: initialData,
        errors: {},
        loading: false,
        submitted: false,

        setField(field, value) {
            this.data[field] = value;
            // Clear error when user starts typing
            if (this.errors[field]) {
                delete this.errors[field];
            }
        },

        setError(field, message) {
            this.errors[field] = message;
        },

        clearErrors() {
            this.errors = {};
        },

        hasError(field) {
            return !!this.errors[field];
        },

        getError(field) {
            return this.errors[field] || '';
        },

        validate(rules = {}) {
            this.clearErrors();
            let isValid = true;

            for (const [field, fieldRules] of Object.entries(rules)) {
                const value = this.data[field];

                if (fieldRules.required && !value) {
                    this.setError(field, `${field} is required`);
                    isValid = false;
                }

                if (fieldRules.email && value && !this.isValidEmail(value)) {
                    this.setError(field, 'Please enter a valid email address');
                    isValid = false;
                }

                if (fieldRules.minLength && value && value.length < fieldRules.minLength) {
                    this.setError(field, `Must be at least ${fieldRules.minLength} characters`);
                    isValid = false;
                }

                if (fieldRules.maxLength && value && value.length > fieldRules.maxLength) {
                    this.setError(field, `Must be no more than ${fieldRules.maxLength} characters`);
                    isValid = false;
                }
            }

            return isValid;
        },

        isValidEmail(email) {
            return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
        },

        async submit(url, options = {}) {
            this.loading = true;
            this.clearErrors();

            try {
                const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]')?.value ||
                                  document.querySelector('meta[name="csrf-token"]')?.content || '';

                const response = await fetch(url, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': csrfToken,
                        ...options.headers
                    },
                    body: JSON.stringify(this.data),
                    ...options
                });

                const result = await response.json();

                if (!response.ok) {
                    if (result.errors) {
                        this.errors = result.errors;
                    }
                    throw new Error(result.message || 'Form submission failed');
                }

                this.submitted = true;
                return result;
            } catch (error) {
                console.error('Form submission error:', error);
                throw error;
            } finally {
                this.loading = false;
            }
        },

        reset() {
            this.data = {};
            this.errors = {};
            this.loading = false;
            this.submitted = false;
        }
    }));

    // =========================================================================
    // Pagination Component
    // =========================================================================

    Alpine.data('pagination', (initialPage = 1, totalPages = 1) => ({
        currentPage: initialPage,
        totalPages: totalPages,

        goToPage(page) {
            if (page >= 1 && page <= this.totalPages) {
                this.currentPage = page;
            }
        },

        nextPage() {
            this.goToPage(this.currentPage + 1);
        },

        prevPage() {
            this.goToPage(this.currentPage - 1);
        },

        hasNext() {
            return this.currentPage < this.totalPages;
        },

        hasPrev() {
            return this.currentPage > 1;
        },

        getPages(maxVisible = 5) {
            const pages = [];
            let start = Math.max(1, this.currentPage - Math.floor(maxVisible / 2));
            let end = Math.min(this.totalPages, start + maxVisible - 1);

            // Adjust start if we're near the end
            if (end - start + 1 < maxVisible) {
                start = Math.max(1, end - maxVisible + 1);
            }

            for (let i = start; i <= end; i++) {
                pages.push(i);
            }

            return pages;
        }
    }));

    // =========================================================================
    // Image Gallery Component
    // =========================================================================

    Alpine.data('imageGallery', (images = []) => ({
        images: images,
        currentIndex: 0,
        lightboxOpen: false,

        get currentImage() {
            return this.images[this.currentIndex] || null;
        },

        openLightbox(index) {
            this.currentIndex = index;
            this.lightboxOpen = true;
            document.body.style.overflow = 'hidden';
        },

        closeLightbox() {
            this.lightboxOpen = false;
            document.body.style.overflow = '';
        },

        next() {
            this.currentIndex = (this.currentIndex + 1) % this.images.length;
        },

        prev() {
            this.currentIndex = (this.currentIndex - 1 + this.images.length) % this.images.length;
        },

        goTo(index) {
            if (index >= 0 && index < this.images.length) {
                this.currentIndex = index;
            }
        }
    }));

    // =========================================================================
    // Rating Component
    // =========================================================================

    Alpine.data('rating', (initialValue = 0, maxStars = 5, readonly = false) => ({
        value: initialValue,
        hoverValue: 0,
        maxStars: maxStars,
        readonly: readonly,

        setRating(rating) {
            if (!this.readonly) {
                this.value = rating;
            }
        },

        setHover(rating) {
            if (!this.readonly) {
                this.hoverValue = rating;
            }
        },

        clearHover() {
            this.hoverValue = 0;
        },

        getDisplayValue() {
            return this.hoverValue || this.value;
        },

        isActive(star) {
            return star <= this.getDisplayValue();
        }
    }));

    // =========================================================================
    // Infinite Scroll Component
    // =========================================================================

    Alpine.data('infiniteScroll', (loadUrl, containerSelector = null) => ({
        loading: false,
        hasMore: true,
        page: 1,

        async loadMore() {
            if (this.loading || !this.hasMore) return;

            this.loading = true;
            this.page++;

            try {
                const url = loadUrl.includes('?')
                    ? `${loadUrl}&page=${this.page}`
                    : `${loadUrl}?page=${this.page}`;

                const response = await fetch(url, {
                    headers: { 'X-Requested-With': 'XMLHttpRequest' }
                });

                if (!response.ok) throw new Error('Failed to load more items');

                const html = await response.text();

                if (html.trim()) {
                    const container = containerSelector
                        ? document.querySelector(containerSelector)
                        : this.$el;

                    if (container) {
                        container.insertAdjacentHTML('beforeend', html);
                    }
                } else {
                    this.hasMore = false;
                }
            } catch (error) {
                console.error('Infinite scroll error:', error);
                this.page--; // Revert page increment on error
            } finally {
                this.loading = false;
            }
        }
    }));

    // =========================================================================
    // Clipboard Component
    // =========================================================================

    Alpine.data('clipboard', () => ({
        copied: false,

        async copy(text) {
            try {
                await navigator.clipboard.writeText(text);
                this.copied = true;
                setTimeout(() => {
                    this.copied = false;
                }, 2000);

                // Show toast notification if available
                if (Alpine.store('toast')) {
                    Alpine.store('toast').success('Copied to clipboard!');
                }
            } catch (error) {
                console.error('Failed to copy:', error);
                if (Alpine.store('toast')) {
                    Alpine.store('toast').error('Failed to copy to clipboard');
                }
            }
        }
    }));

    // Log initialization
    console.log('Alpine.js components initialized');
});
