/**
 * GeoFilterHandler - Manages location filtering and category selection on the map
 * 
 * Features:
 * - Properly handles parent-child category relationships
 * - Maintains UI state for expanded/collapsed categories
 * - Ensures child categories are shown when parent is selected
 * - Automatically resets previous selections when switching parent categories
 */

class GeoFilterHandler {
    constructor(options) {
        this.apiBaseUrl = options.apiBaseUrl || '/public/api/';
        this.mapInstance = options.mapInstance;
        this.locationsCache = {}; // Cache API responses by category
        this.activeCategory = null;
        this.expandedParents = new Set(); // Track which parent categories are expanded
        this.parentChildMap = {}; // Map of parent categories to their child categories
        this.categoryCountMap = {}; // Map of categories to their location counts
        this.isLoadingLocations = false;
        
        // UI elements
        this.categoryPills = document.querySelectorAll('.category-pill');
        this.clearFilterBtn = document.getElementById('clearFilter');
        this.locationsList = document.getElementById('locationsList');
        
        // Initialize
        this.buildParentChildMap();
        this.attachEventListeners();
        console.log('Initializing category system');
    }
    
    /**
     * Build a map of parent categories to their children
     */
    buildParentChildMap() {
        const parentElements = document.querySelectorAll('.parent-category');
        
        parentElements.forEach(parent => {
            const parentId = parseInt(parent.dataset.categoryId, 10);
            const childrenContainer = parent.nextElementSibling;
            
            if (childrenContainer && childrenContainer.classList.contains('subcategories')) {
                const children = childrenContainer.querySelectorAll('.category-pill');
                this.parentChildMap[parentId] = Array.from(children).map(child => 
                    parseInt(child.dataset.categoryId, 10)
                );
            }
        });
        
        console.log('Parent-child relationship map built:', this.parentChildMap);
    }
    
    /**
     * Attach event listeners to category pills and other UI elements
     */
    attachEventListeners() {
        // Clear filter button
        if (this.clearFilterBtn) {
            this.clearFilterBtn.addEventListener('click', () => this.clearFilters());
        }
        
        // All category pills
        this.reconnectCategoryListeners();
        
        console.log('Category system initialized');
    }
    
    /**
     * Reconnect event listeners to category pills
     * Important: This should be called after any DOM changes that affect the category pills
     */
    reconnectCategoryListeners() {
        // Remove any existing listeners first
        const allPills = document.querySelectorAll('.category-pill');
        allPills.forEach(pill => {
            const newPill = pill.cloneNode(true);
            pill.parentNode.replaceChild(newPill, pill);
        });
        
        // Add click handler to 'All' button
        const allButton = document.querySelector('.all-categories');
        if (allButton) {
            allButton.addEventListener('click', () => this.clearFilters());
            console.log('Added click handler to \'All\' button');
        }
        
        // Add click handlers to child category pills
        const childPills = document.querySelectorAll('.subcategories .category-pill');
        childPills.forEach(pill => {
            pill.addEventListener('click', (e) => this.handleCategoryPillClick(e));
        });
        console.log(`Added click handlers to ${childPills.length} child categories`);
        
        // Add click handlers to parent category pills
        const parentPills = document.querySelectorAll('.parent-category');
        parentPills.forEach(pill => {
            pill.addEventListener('click', (e) => this.handleParentCategoryClick(e));
        });
        console.log(`Added click handlers to ${parentPills.length} parent categories`);
        
        // Ensure the subcategories are shown for the active category
        this.showSubcategoriesForActiveCategory();
    }
    
    /**
     * Handle click on a category pill
     */
    handleCategoryPillClick(event) {
        const pill = event.currentTarget;
        const categoryId = parseInt(pill.dataset.categoryId, 10);
        
        console.log(`Category pill clicked: ${pill.id} (ID: ${categoryId})`);
        
        // Remove active class from all pills
        document.querySelectorAll('.category-pill').forEach(p => {
            p.classList.remove('active');
        });
        
        // Add active class to clicked pill
        pill.classList.add('active');
        
        // Update filter and fetch locations
        console.log(`Category filter changed to category ID: ${categoryId}`);
        this.applyFilter(categoryId);
    }
    
    /**
     * Handle click on a parent category
     */
    handleParentCategoryClick(event) {
        const parentPill = event.currentTarget;
        const parentId = parseInt(parentPill.dataset.categoryId, 10);
        
        console.log(`Parent category ${parentId} clicked - applying filter`);
        
        // Show subcategories for this parent
        this.ensureSubcategoriesShown(parentId);
        
        // Store in expanded parents set
        this.expandedParents.add(parentId.toString());
        
        // Apply filter with include_children=true
        this.applyFilter(parentId, true);
    }
    
    /**
     * Ensure subcategories for specified parent are visible
     */
    ensureSubcategoriesShown(parentId) {
        console.log(`Ensuring subcategories are shown for selected category: ${parentId}`);
        
        // Find the subcategories container for this parent
        const parent = document.querySelector(`.parent-category[data-category-id="${parentId}"]`);
        if (parent) {
            const subCatContainer = parent.nextElementSibling;
            if (subCatContainer && subCatContainer.classList.contains('subcategories')) {
                subCatContainer.style.display = 'flex';
                
                // Make sure each child category is directly visible
                const childCategories = this.parentChildMap[parentId] || [];
                childCategories.forEach(childId => {
                    console.log(`Direct display of child category: ${childId} of parent ${parentId}`);
                    const childElement = document.querySelector(`.category-pill[data-category-id="${childId}"]`);
                    if (childElement) {
                        childElement.style.display = 'flex';
                    }
                });
            }
        }
        
        // Add a special style to force display
        this.addForcedDisplayStyle();
    }
    
    /**
     * Apply category filter and fetch locations
     */
    applyFilter(categoryId, includeChildren = false) {
        this.activeCategory = categoryId;
        
        console.log(`Active category filter: ${categoryId}`);
        
        // Construct API parameters
        const params = new URLSearchParams();
        params.append('category_id', categoryId);
        params.append('is_active', 1);
        
        if (includeChildren) {
            console.log('Including child categories in API request');
            params.append('include_children', 1);
        }
        
        // Check cache first
        const cacheKey = params.toString();
        if (this.locationsCache[cacheKey]) {
            console.log('Using cached response for', cacheKey);
            this.updateMapWithLocations(this.locationsCache[cacheKey]);
            return;
        }
        
        // Fetch locations from API
        const url = `${this.apiBaseUrl}locations?${params.toString()}`;
        console.log(`Fetching locations from: ${url}`);
        
        this.isLoadingLocations = true;
        fetch(url)
            .then(response => response.json())
            .then(data => {
                // Store in cache
                this.locationsCache[cacheKey] = data;
                
                // Check for meta property in the response
                if (data.meta && data.meta.should_reset_previous) {
                    // The API is telling us to reset previous selections
                    console.log('API requested reset of previous selections');
                }
                
                // Update the map with the locations
                this.updateMapWithLocations(data);
                this.isLoadingLocations = false;
            })
            .catch(error => {
                console.error('Error fetching locations:', error);
                this.isLoadingLocations = false;
            });
    }
    
    /**
     * Update the map with filtered locations
     */
    updateMapWithLocations(apiResponse) {
        // Get locations from response (handle both formats)
        const locations = apiResponse.locations || apiResponse;
        
        // Update the map
        if (typeof this.mapInstance?.updateLocations === 'function') {
            this.mapInstance.updateLocations(locations);
        } else if (window.updateMapLocations) {
            window.updateMapLocations(locations);
        } else {
            console.error('No map update function available');
        }
        
        // Update the category counts based on the filtered locations
        console.log(`Updating categories based on filtered locations: ${locations.length}`);
        console.log(`Preserving state - Active category: ${this.activeCategory} Expanded parents: ${Array.from(this.expandedParents)}`);
        
        // Update category counts
        this.updateCategoryCounts(locations);
        
        // Force display child categories that should be shown
        this.forceShowChildCategories();
    }
    
    /**
     * FORCIBLY show subcategories for active and expanded categories
     * This overrides any display:none that might be set by the map script
     */
    forceShowChildCategories() {
        console.log('FORCIBLY showing subcategories for selected categories');
        
        // First, reset all subcategories to their default state
        document.querySelectorAll('.subcategories').forEach(container => {
            container.style.display = ''; // Reset to CSS default
        });
        
        // Then force active category's subcategories to show
        if (this.activeCategory) {
            // Check if this is a parent category
            if (this.parentChildMap[this.activeCategory]) {
                console.log(`FORCE: Showing subcategories for active parent ${this.activeCategory}`);
                const parent = document.querySelector(`.parent-category[data-category-id="${this.activeCategory}"]`);
                if (parent) {
                    const subCatContainer = parent.nextElementSibling;
                    if (subCatContainer && subCatContainer.classList.contains('subcategories')) {
                        subCatContainer.style.display = 'flex';
                        
                        // Ensure child categories are visible
                        this.parentChildMap[this.activeCategory].forEach(childId => {
                            console.log(`FORCE: Showing child category ${childId}`);
                            const childElement = document.querySelector(`.category-pill[data-category-id="${childId}"]`);
                            if (childElement) {
                                childElement.style.display = 'flex';
                            }
                        });
                    }
                }
            }
        }
        
        // Force subcategories for expanded parents
        this.expandedParents.forEach(parentId => {
            console.log(`FORCE: Showing subcategories for expanded parent ${parentId}`);
            const parent = document.querySelector(`.parent-category[data-category-id="${parentId}"]`);
            if (parent) {
                const subCatContainer = parent.nextElementSibling;
                if (subCatContainer && subCatContainer.classList.contains('subcategories')) {
                    subCatContainer.style.display = 'flex';
                    
                    // Ensure child categories are visible
                    (this.parentChildMap[parentId] || []).forEach(childId => {
                        console.log(`FORCE: Showing child category ${childId}`);
                        const childElement = document.querySelector(`.category-pill[data-category-id="${childId}"]`);
                        if (childElement) {
                            childElement.style.display = 'flex';
                        }
                    });
                }
            }
        });
        
        // Add the forced style again
        this.addForcedDisplayStyle();
    }
    
    /**
     * Add a style tag to force display of subcategories
     */
    addForcedDisplayStyle() {
        // Remove any existing style tag
        const existingStyle = document.getElementById('forced-subcategory-style');
        if (existingStyle) {
            existingStyle.remove();
        }
        
        // Create a new style tag
        const style = document.createElement('style');
        style.id = 'forced-subcategory-style';
        style.textContent = `
            .parent-category.active + .subcategories, 
            .parent-category.expanded + .subcategories {
                display: flex !important;
            }
            
            .subcategories[style*="display: flex"] .category-pill,
            .subcategories[style*="display:flex"] .category-pill {
                display: flex !important;
            }
        `;
        document.head.appendChild(style);
        console.log('Directly manipulating CSS to show subcategories');
    }
    
    /**
     * Restore child categories display state
     */
    restoreChildCategoriesDisplay() {
        console.log('Restoring child categories display state');
        
        // Get all subcategories containers that should be visible
        const visibleContainers = [];
        
        // Add container for active category
        if (this.activeCategory) {
            // Find the parent of this category
            for (const [parentId, children] of Object.entries(this.parentChildMap)) {
                if (children.includes(parseInt(this.activeCategory))) {
                    visibleContainers.push(parentId);
                    break;
                }
            }
        }
        
        // Add containers for expanded parents
        this.expandedParents.forEach(parentId => {
            visibleContainers.push(parentId);
        });
        
        // Force display for all child categories in visible containers
        visibleContainers.forEach(parentId => {
            const children = this.parentChildMap[parentId] || [];
            children.forEach(childId => {
                console.log(`Restoring display for child category ${childId}`);
                const childElement = document.querySelector(`.category-pill[data-category-id="${childId}"]`);
                if (childElement) {
                    childElement.style.display = 'flex';
                }
            });
        });
    }
    
    /**
     * Update category counts based on the current locations
     */
    updateCategoryCounts(locations) {
        if (typeof window.updateCategoryCounts === 'function') {
            window.updateCategoryCounts(locations);
        }
        
        // Store the counts for our own use
        this.categoryCountMap = {};
        locations.forEach(location => {
            const categoryId = location.category_id;
            if (categoryId) {
                this.categoryCountMap[categoryId] = (this.categoryCountMap[categoryId] || 0) + 1;
            }
        });
    }
    
    /**
     * Clear all filters and show all locations
     */
    clearFilters() {
        console.log('Clearing all filters');
        
        // Reset active category
        this.activeCategory = null;
        
        // Remove active class from all pills
        document.querySelectorAll('.category-pill').forEach(pill => {
            pill.classList.remove('active');
        });
        
        // Fetch all locations
        const params = new URLSearchParams();
        params.append('is_active', 1);
        
        const url = `${this.apiBaseUrl}locations?${params.toString()}`;
        console.log(`Fetching all locations from: ${url}`);
        
        fetch(url)
            .then(response => response.json())
            .then(data => {
                // Update the map with the locations
                this.updateMapWithLocations(data);
            })
            .catch(error => {
                console.error('Error fetching locations:', error);
            });
    }
    
    /**
     * Show subcategories for the active category
     */
    showSubcategoriesForActiveCategory() {
        if (this.activeCategory) {
            // For parent categories
            if (this.parentChildMap[this.activeCategory]) {
                this.ensureSubcategoriesShown(this.activeCategory);
            } else {
                // For child categories, find the parent
                for (const [parentId, children] of Object.entries(this.parentChildMap)) {
                    if (children.includes(parseInt(this.activeCategory))) {
                        this.ensureSubcategoriesShown(parseInt(parentId));
                        break;
                    }
                }
            }
        }
    }
}

// Initialize on DOMContentLoaded
document.addEventListener('DOMContentLoaded', () => {
    // Delay initialization to let the map load first
    setTimeout(() => {
        // Create the filter handler
        window.geoFilterHandler = new GeoFilterHandler({
            apiBaseUrl: window.location.origin + '/api/',
            mapInstance: window.mapInstance
        });
    }, 500);
}); 