/**
 * ThrillWiki Dark Mode Maps - Dark Mode Integration for Maps
 * 
 * This module provides comprehensive dark mode support for maps,
 * including automatic theme switching, dark tile layers, and consistent styling
 */

class DarkModeMaps {
    constructor(options = {}) {
        this.options = {
            enableAutoThemeDetection: true,
            enableSystemPreference: true,
            enableStoredPreference: true,
            storageKey: 'thrillwiki_dark_mode',
            transitionDuration: 300,
            tileProviders: {
                light: {
                    osm: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                    cartodb: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png'
                },
                dark: {
                    osm: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',
                    cartodb: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png'
                }
            },
            ...options
        };
        
        this.currentTheme = 'light';
        this.mapInstances = new Set();
        this.tileLayers = new Map();
        this.observer = null;
        this.mediaQuery = null;
        
        this.init();
    }
    
    /**
     * Initialize dark mode support
     */
    init() {
        this.detectCurrentTheme();
        this.setupThemeObserver();
        this.setupSystemPreferenceDetection();
        this.setupStorageSync();
        this.setupMapThemeStyles();
        this.bindEventHandlers();
        
        console.log('Dark mode maps initialized with theme:', this.currentTheme);
    }
    
    /**
     * Detect current theme from DOM
     */
    detectCurrentTheme() {
        if (document.documentElement.classList.contains('dark')) {
            this.currentTheme = 'dark';
        } else {
            this.currentTheme = 'light';
        }
        
        // Check stored preference
        if (this.options.enableStoredPreference) {
            const stored = localStorage.getItem(this.options.storageKey);
            if (stored && ['light', 'dark', 'auto'].includes(stored)) {
                this.applyStoredPreference(stored);
            }
        }
        
        // Check system preference if auto
        if (this.options.enableSystemPreference && this.getStoredPreference() === 'auto') {
            this.applySystemPreference();
        }
    }
    
    /**
     * Setup theme observer to watch for changes
     */
    setupThemeObserver() {
        this.observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.attributeName === 'class') {
                    const newTheme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
                    
                    if (newTheme !== this.currentTheme) {
                        this.handleThemeChange(newTheme);
                    }
                }
            });
        });
        
        this.observer.observe(document.documentElement, {
            attributes: true,
            attributeFilter: ['class']
        });
    }
    
    /**
     * Setup system preference detection
     */
    setupSystemPreferenceDetection() {
        if (!this.options.enableSystemPreference) return;
        
        this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
        
        const handleSystemChange = (e) => {
            if (this.getStoredPreference() === 'auto') {
                const newTheme = e.matches ? 'dark' : 'light';
                this.setTheme(newTheme);
            }
        };
        
        // Modern browsers
        if (this.mediaQuery.addEventListener) {
            this.mediaQuery.addEventListener('change', handleSystemChange);
        } else {
            // Fallback for older browsers
            this.mediaQuery.addListener(handleSystemChange);
        }
    }
    
    /**
     * Setup storage synchronization
     */
    setupStorageSync() {
        // Listen for storage changes from other tabs
        window.addEventListener('storage', (e) => {
            if (e.key === this.options.storageKey) {
                const newPreference = e.newValue;
                if (newPreference) {
                    this.applyStoredPreference(newPreference);
                }
            }
        });
    }
    
    /**
     * Setup map theme styles
     */
    setupMapThemeStyles() {
        if (document.getElementById('dark-mode-map-styles')) return;
        
        const styles = `
            <style id="dark-mode-map-styles">
                /* Light theme map styles */
                .map-container {
                    transition: filter ${this.options.transitionDuration}ms ease;
                }
                
                /* Dark theme map styles */
                .dark .map-container {
                    filter: brightness(0.9) contrast(1.1);
                }
                
                /* Dark theme popup styles */
                .dark .leaflet-popup-content-wrapper {
                    background: #1F2937;
                    color: #F9FAFB;
                    border: 1px solid #374151;
                }
                
                .dark .leaflet-popup-tip {
                    background: #1F2937;
                    border: 1px solid #374151;
                }
                
                .dark .leaflet-popup-close-button {
                    color: #D1D5DB;
                }
                
                .dark .leaflet-popup-close-button:hover {
                    color: #F9FAFB;
                }
                
                /* Dark theme control styles */
                .dark .leaflet-control-zoom a {
                    background-color: #374151;
                    border-color: #4B5563;
                    color: #F9FAFB;
                }
                
                .dark .leaflet-control-zoom a:hover {
                    background-color: #4B5563;
                }
                
                .dark .leaflet-control-attribution {
                    background: rgba(31, 41, 55, 0.8);
                    color: #D1D5DB;
                }
                
                /* Dark theme marker cluster styles */
                .dark .cluster-marker-inner {
                    background: #1E40AF;
                    border-color: #1F2937;
                }
                
                .dark .cluster-marker-medium .cluster-marker-inner {
                    background: #059669;
                }
                
                .dark .cluster-marker-large .cluster-marker-inner {
                    background: #DC2626;
                }
                
                /* Dark theme location marker styles */
                .dark .location-marker-inner {
                    border-color: #1F2937;
                    box-shadow: 0 2px 8px rgba(0,0,0,0.6);
                }
                
                /* Dark theme filter panel styles */
                .dark .filter-chip.active {
                    background: #1E40AF;
                    color: #F9FAFB;
                }
                
                .dark .filter-chip.inactive {
                    background: #374151;
                    color: #D1D5DB;
                }
                
                .dark .filter-chip.inactive:hover {
                    background: #4B5563;
                }
                
                /* Dark theme road trip styles */
                .dark .park-item {
                    background: #374151;
                    border-color: #4B5563;
                }
                
                .dark .park-item:hover {
                    background: #4B5563;
                }
                
                /* Dark theme search results */
                .dark .search-result-item {
                    background: #374151;
                    border-color: #4B5563;
                }
                
                .dark .search-result-item:hover {
                    background: #4B5563;
                }
                
                /* Dark theme loading indicators */
                .dark .htmx-indicator {
                    color: #D1D5DB;
                }
                
                /* Theme transition effects */
                .theme-transition {
                    transition: background-color ${this.options.transitionDuration}ms ease,
                               color ${this.options.transitionDuration}ms ease,
                               border-color ${this.options.transitionDuration}ms ease;
                }
                
                /* Dark theme toggle button */
                .theme-toggle {
                    position: relative;
                    width: 48px;
                    height: 24px;
                    background: #E5E7EB;
                    border-radius: 12px;
                    border: none;
                    cursor: pointer;
                    transition: background-color ${this.options.transitionDuration}ms ease;
                }
                
                .dark .theme-toggle {
                    background: #374151;
                }
                
                .theme-toggle::after {
                    content: '';
                    position: absolute;
                    top: 2px;
                    left: 2px;
                    width: 20px;
                    height: 20px;
                    background: white;
                    border-radius: 50%;
                    transition: transform ${this.options.transitionDuration}ms ease;
                    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
                }
                
                .dark .theme-toggle::after {
                    transform: translateX(24px);
                    background: #F9FAFB;
                }
                
                /* Theme icons */
                .theme-icon {
                    position: absolute;
                    top: 50%;
                    transform: translateY(-50%);
                    font-size: 12px;
                    transition: opacity ${this.options.transitionDuration}ms ease;
                }
                
                .theme-icon.sun {
                    left: 4px;
                    color: #F59E0B;
                    opacity: 1;
                }
                
                .theme-icon.moon {
                    right: 4px;
                    color: #6366F1;
                    opacity: 0;
                }
                
                .dark .theme-icon.sun {
                    opacity: 0;
                }
                
                .dark .theme-icon.moon {
                    opacity: 1;
                }
                
                /* System preference indicator */
                .theme-auto-indicator {
                    font-size: 10px;
                    opacity: 0.6;
                    margin-left: 4px;
                }
            </style>
        `;
        
        document.head.insertAdjacentHTML('beforeend', styles);
    }
    
    /**
     * Bind event handlers
     */
    bindEventHandlers() {
        // Handle theme toggle buttons
        const themeToggleButtons = document.querySelectorAll('[data-theme-toggle]');
        themeToggleButtons.forEach(button => {
            button.addEventListener('click', () => {
                this.toggleTheme();
            });
        });
        
        // Handle theme selection
        const themeSelectors = document.querySelectorAll('[data-theme-select]');
        themeSelectors.forEach(selector => {
            selector.addEventListener('change', (e) => {
                this.setThemePreference(e.target.value);
            });
        });
    }
    
    /**
     * Handle theme change
     */
    handleThemeChange(newTheme) {
        const oldTheme = this.currentTheme;
        this.currentTheme = newTheme;
        
        // Update map tile layers
        this.updateMapTileLayers(newTheme);
        
        // Update marker themes
        this.updateMarkerThemes(newTheme);
        
        // Emit theme change event
        const event = new CustomEvent('themeChanged', {
            detail: { 
                oldTheme, 
                newTheme,
                isSystemPreference: this.getStoredPreference() === 'auto'
            }
        });
        document.dispatchEvent(event);
        
        console.log(`Theme changed from ${oldTheme} to ${newTheme}`);
    }
    
    /**
     * Update map tile layers for theme
     */
    updateMapTileLayers(theme) {
        this.mapInstances.forEach(mapInstance => {
            const currentTileLayer = this.tileLayers.get(mapInstance);
            
            if (currentTileLayer) {
                mapInstance.removeLayer(currentTileLayer);
            }
            
            // Create new tile layer for theme
            const tileUrl = this.options.tileProviders[theme].osm;
            const newTileLayer = L.tileLayer(tileUrl, {
                attribution: '© OpenStreetMap contributors' + (theme === 'dark' ? ', © CARTO' : ''),
                className: `map-tiles-${theme}`
            });
            
            newTileLayer.addTo(mapInstance);
            this.tileLayers.set(mapInstance, newTileLayer);
        });
    }
    
    /**
     * Update marker themes
     */
    updateMarkerThemes(theme) {
        if (window.mapMarkers) {
            // Clear marker caches to force re-render with new theme
            window.mapMarkers.clearIconCache();
            window.mapMarkers.clearPopupCache();
        }
    }
    
    /**
     * Toggle between light and dark themes
     */
    toggleTheme() {
        const newTheme = this.currentTheme === 'light' ? 'dark' : 'light';
        this.setTheme(newTheme);
        this.setStoredPreference(newTheme);
    }
    
    /**
     * Set specific theme
     */
    setTheme(theme) {
        if (!['light', 'dark'].includes(theme)) return;
        
        if (theme === 'dark') {
            document.documentElement.classList.add('dark');
        } else {
            document.documentElement.classList.remove('dark');
        }
        
        // Update theme toggle states
        this.updateThemeToggleStates(theme);
    }
    
    /**
     * Set theme preference (light, dark, auto)
     */
    setThemePreference(preference) {
        if (!['light', 'dark', 'auto'].includes(preference)) return;
        
        this.setStoredPreference(preference);
        
        if (preference === 'auto') {
            this.applySystemPreference();
        } else {
            this.setTheme(preference);
        }
    }
    
    /**
     * Apply system preference
     */
    applySystemPreference() {
        if (this.mediaQuery) {
            const systemPrefersDark = this.mediaQuery.matches;
            this.setTheme(systemPrefersDark ? 'dark' : 'light');
        }
    }
    
    /**
     * Apply stored preference
     */
    applyStoredPreference(preference) {
        if (preference === 'auto') {
            this.applySystemPreference();
        } else {
            this.setTheme(preference);
        }
    }
    
    /**
     * Get stored theme preference
     */
    getStoredPreference() {
        return localStorage.getItem(this.options.storageKey) || 'auto';
    }
    
    /**
     * Set stored theme preference
     */
    setStoredPreference(preference) {
        localStorage.setItem(this.options.storageKey, preference);
    }
    
    /**
     * Update theme toggle button states
     */
    updateThemeToggleStates(theme) {
        const toggleButtons = document.querySelectorAll('[data-theme-toggle]');
        toggleButtons.forEach(button => {
            button.setAttribute('data-theme', theme);
            button.setAttribute('aria-label', `Switch to ${theme === 'light' ? 'dark' : 'light'} theme`);
        });
        
        const themeSelectors = document.querySelectorAll('[data-theme-select]');
        themeSelectors.forEach(selector => {
            selector.value = this.getStoredPreference();
        });
    }
    
    /**
     * Register map instance for theme management
     */
    registerMapInstance(mapInstance) {
        this.mapInstances.add(mapInstance);
        
        // Apply current theme immediately
        setTimeout(() => {
            this.updateMapTileLayers(this.currentTheme);
        }, 100);
    }
    
    /**
     * Unregister map instance
     */
    unregisterMapInstance(mapInstance) {
        this.mapInstances.delete(mapInstance);
        this.tileLayers.delete(mapInstance);
    }
    
    /**
     * Create theme toggle button
     */
    createThemeToggle() {
        const toggle = document.createElement('button');
        toggle.className = 'theme-toggle';
        toggle.setAttribute('data-theme-toggle', 'true');
        toggle.setAttribute('aria-label', 'Toggle theme');
        toggle.innerHTML = `
            <i class="theme-icon sun fas fa-sun"></i>
            <i class="theme-icon moon fas fa-moon"></i>
        `;
        
        toggle.addEventListener('click', () => {
            this.toggleTheme();
        });
        
        return toggle;
    }
    
    /**
     * Create theme selector dropdown
     */
    createThemeSelector() {
        const selector = document.createElement('select');
        selector.className = 'theme-selector';
        selector.setAttribute('data-theme-select', 'true');
        selector.innerHTML = `
            <option value="auto">Auto</option>
            <option value="light">Light</option>
            <option value="dark">Dark</option>
        `;
        
        selector.value = this.getStoredPreference();
        
        selector.addEventListener('change', (e) => {
            this.setThemePreference(e.target.value);
        });
        
        return selector;
    }
    
    /**
     * Get current theme
     */
    getCurrentTheme() {
        return this.currentTheme;
    }
    
    /**
     * Check if dark mode is active
     */
    isDarkMode() {
        return this.currentTheme === 'dark';
    }
    
    /**
     * Check if system preference is supported
     */
    isSystemPreferenceSupported() {
        return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').media !== 'not all';
    }
    
    /**
     * Get system preference
     */
    getSystemPreference() {
        if (this.isSystemPreferenceSupported() && this.mediaQuery) {
            return this.mediaQuery.matches ? 'dark' : 'light';
        }
        return 'light';
    }
    
    /**
     * Add theme transition classes
     */
    addThemeTransitions() {
        const elements = document.querySelectorAll('.filter-chip, .park-item, .search-result-item, .popup-btn');
        elements.forEach(element => {
            element.classList.add('theme-transition');
        });
    }
    
    /**
     * Remove theme transition classes
     */
    removeThemeTransitions() {
        const elements = document.querySelectorAll('.theme-transition');
        elements.forEach(element => {
            element.classList.remove('theme-transition');
        });
    }
    
    /**
     * Destroy dark mode instance
     */
    destroy() {
        if (this.observer) {
            this.observer.disconnect();
        }
        
        if (this.mediaQuery) {
            if (this.mediaQuery.removeEventListener) {
                this.mediaQuery.removeEventListener('change', this.applySystemPreference);
            } else {
                this.mediaQuery.removeListener(this.applySystemPreference);
            }
        }
        
        this.mapInstances.clear();
        this.tileLayers.clear();
    }
}

// Auto-initialize dark mode support
document.addEventListener('DOMContentLoaded', function() {
    window.darkModeMaps = new DarkModeMaps();
    
    // Register existing map instances
    if (window.thrillwikiMap) {
        window.darkModeMaps.registerMapInstance(window.thrillwikiMap);
    }
    
    // Add theme transitions
    window.darkModeMaps.addThemeTransitions();
    
    // Add theme toggle to navigation if it doesn't exist
    const nav = document.querySelector('nav, .navbar, .header-nav');
    if (nav && !nav.querySelector('[data-theme-toggle]')) {
        const themeToggle = window.darkModeMaps.createThemeToggle();
        themeToggle.style.marginLeft = 'auto';
        nav.appendChild(themeToggle);
    }
});

// Export for use in other modules
if (typeof module !== 'undefined' && module.exports) {
    module.exports = DarkModeMaps;
} else {
    window.DarkModeMaps = DarkModeMaps;
}