/**
 * ThrillWiki Mobile Touch Support - Enhanced Mobile and Touch Experience
 * 
 * This module provides mobile-optimized interactions, touch-friendly controls,
 * responsive map sizing, and battery-conscious features for mobile devices
 */

class MobileTouchSupport {
    constructor(options = {}) {
        this.options = {
            enableTouchOptimizations: true,
            enableSwipeGestures: true,
            enablePinchZoom: true,
            enableResponsiveResize: true,
            enableBatteryOptimization: true,
            touchDebounceDelay: 150,
            swipeThreshold: 50,
            swipeVelocityThreshold: 0.3,
            maxTouchPoints: 2,
            orientationChangeDelay: 300,
            ...options
        };
        
        this.isMobile = this.detectMobileDevice();
        this.isTouch = this.detectTouchSupport();
        this.orientation = this.getOrientation();
        this.mapInstances = new Set();
        this.touchHandlers = new Map();
        this.gestureState = {
            isActive: false,
            startDistance: 0,
            startCenter: null,
            lastTouchTime: 0
        };
        
        this.init();
    }
    
    /**
     * Initialize mobile touch support
     */
    init() {
        if (!this.isTouch && !this.isMobile) {
            console.log('Mobile touch support not needed for this device');
            return;
        }
        
        this.setupTouchOptimizations();
        this.setupSwipeGestures();
        this.setupResponsiveHandling();
        this.setupBatteryOptimization();
        this.setupAccessibilityEnhancements();
        this.bindEventHandlers();
        
        console.log('Mobile touch support initialized');
    }
    
    /**
     * Detect if device is mobile
     */
    detectMobileDevice() {
        const userAgent = navigator.userAgent.toLowerCase();
        const mobileKeywords = ['android', 'iphone', 'ipad', 'ipod', 'blackberry', 'windows phone'];
        
        return mobileKeywords.some(keyword => userAgent.includes(keyword)) ||
               window.innerWidth <= 768 ||
               (typeof window.orientation !== 'undefined');
    }
    
    /**
     * Detect touch support
     */
    detectTouchSupport() {
        return 'ontouchstart' in window ||
               navigator.maxTouchPoints > 0 ||
               navigator.msMaxTouchPoints > 0;
    }
    
    /**
     * Get current orientation
     */
    getOrientation() {
        if (screen.orientation) {
            return screen.orientation.angle;
        } else if (window.orientation !== undefined) {
            return window.orientation;
        }
        return window.innerWidth > window.innerHeight ? 90 : 0;
    }
    
    /**
     * Setup touch optimizations
     */
    setupTouchOptimizations() {
        if (!this.options.enableTouchOptimizations) return;
        
        // Add touch-optimized styles
        this.addTouchStyles();
        
        // Enhance touch targets
        this.enhanceTouchTargets();
        
        // Optimize scroll behavior
        this.optimizeScrollBehavior();
        
        // Setup touch feedback
        this.setupTouchFeedback();
    }
    
    /**
     * Add touch-optimized CSS styles
     */
    addTouchStyles() {
        if (document.getElementById('mobile-touch-styles')) return;
        
        const styles = `
            <style id="mobile-touch-styles">
                @media (max-width: 768px) {
                    /* Touch-friendly button sizes */
                    .btn, button, .filter-chip, .filter-pill {
                        min-height: 44px;
                        min-width: 44px;
                        padding: 12px 16px;
                        font-size: 16px;
                    }
                    
                    /* Larger touch targets for map controls */
                    .leaflet-control-zoom a {
                        width: 44px !important;
                        height: 44px !important;
                        line-height: 44px !important;
                        font-size: 18px !important;
                    }
                    
                    /* Mobile-optimized map containers */
                    .map-container {
                        height: 60vh !important;
                        min-height: 300px !important;
                    }
                    
                    /* Touch-friendly popup styling */
                    .leaflet-popup-content-wrapper {
                        border-radius: 12px;
                        box-shadow: 0 4px 20px rgba(0,0,0,0.15);
                    }
                    
                    .leaflet-popup-content {
                        margin: 16px 20px;
                        font-size: 16px;
                        line-height: 1.5;
                    }
                    
                    /* Improved form controls */
                    input, select, textarea {
                        font-size: 16px !important; /* Prevents zoom on iOS */
                        padding: 12px;
                        border-radius: 8px;
                    }
                    
                    /* Touch-friendly filter panels */
                    .filter-panel {
                        padding: 16px;
                        border-radius: 12px;
                    }
                    
                    /* Mobile navigation improvements */
                    .roadtrip-planner {
                        padding: 16px;
                    }
                    
                    .parks-list .park-item {
                        padding: 16px;
                        margin-bottom: 12px;
                        border-radius: 12px;
                        touch-action: manipulation;
                    }
                    
                    /* Swipe indicators */
                    .swipe-indicator {
                        position: absolute;
                        top: 50%;
                        transform: translateY(-50%);
                        width: 4px;
                        height: 40px;
                        background: rgba(59, 130, 246, 0.5);
                        border-radius: 2px;
                        transition: opacity 0.3s ease;
                    }
                    
                    .swipe-indicator.left {
                        left: 8px;
                    }
                    
                    .swipe-indicator.right {
                        right: 8px;
                    }
                }
                
                @media (max-width: 480px) {
                    /* Extra small screens */
                    .map-container {
                        height: 50vh !important;
                    }
                    
                    .filter-panel {
                        position: fixed;
                        bottom: 0;
                        left: 0;
                        right: 0;
                        z-index: 1000;
                        max-height: 50vh;
                        overflow-y: auto;
                        border-radius: 16px 16px 0 0;
                        box-shadow: 0 -4px 20px rgba(0,0,0,0.15);
                    }
                }
                
                /* Touch feedback */
                .touch-feedback {
                    position: relative;
                    overflow: hidden;
                }
                
                .touch-feedback::after {
                    content: '';
                    position: absolute;
                    top: 50%;
                    left: 50%;
                    width: 0;
                    height: 0;
                    border-radius: 50%;
                    background: rgba(255, 255, 255, 0.3);
                    transform: translate(-50%, -50%);
                    transition: width 0.3s ease, height 0.3s ease;
                    pointer-events: none;
                }
                
                .touch-feedback.active::after {
                    width: 100px;
                    height: 100px;
                }
                
                /* Prevent text selection on mobile */
                .no-select {
                    -webkit-touch-callout: none;
                    -webkit-user-select: none;
                    -khtml-user-select: none;
                    -moz-user-select: none;
                    -ms-user-select: none;
                    user-select: none;
                }
                
                /* Optimize touch scrolling */
                .touch-scroll {
                    -webkit-overflow-scrolling: touch;
                    overflow-scrolling: touch;
                }
            </style>
        `;
        
        document.head.insertAdjacentHTML('beforeend', styles);
    }
    
    /**
     * Enhance touch targets for better accessibility
     */
    enhanceTouchTargets() {
        const smallTargets = document.querySelectorAll('button, .btn, a, input[type="checkbox"], input[type="radio"]');
        
        smallTargets.forEach(target => {
            const rect = target.getBoundingClientRect();
            
            // If target is smaller than 44px (Apple's recommended minimum), enhance it
            if (rect.width < 44 || rect.height < 44) {
                target.classList.add('touch-enhanced');
                target.style.minWidth = '44px';
                target.style.minHeight = '44px';
                target.style.display = 'inline-flex';
                target.style.alignItems = 'center';
                target.style.justifyContent = 'center';
            }
        });
    }
    
    /**
     * Optimize scroll behavior for mobile
     */
    optimizeScrollBehavior() {
        // Add momentum scrolling to scrollable elements
        const scrollableElements = document.querySelectorAll('.scrollable, .overflow-auto, .overflow-y-auto');
        
        scrollableElements.forEach(element => {
            element.classList.add('touch-scroll');
            element.style.webkitOverflowScrolling = 'touch';
        });
        
        // Prevent body scroll when interacting with maps
        document.addEventListener('touchstart', (e) => {
            if (e.target.closest('.leaflet-container')) {
                e.preventDefault();
            }
        }, { passive: false });
    }
    
    /**
     * Setup touch feedback for interactive elements
     */
    setupTouchFeedback() {
        const interactiveElements = document.querySelectorAll('button, .btn, .filter-chip, .filter-pill, .park-item');
        
        interactiveElements.forEach(element => {
            element.classList.add('touch-feedback');
            
            element.addEventListener('touchstart', (e) => {
                element.classList.add('active');
                
                setTimeout(() => {
                    element.classList.remove('active');
                }, 300);
            }, { passive: true });
        });
    }
    
    /**
     * Setup swipe gesture support
     */
    setupSwipeGestures() {
        if (!this.options.enableSwipeGestures) return;
        
        let touchStartX = 0;
        let touchStartY = 0;
        let touchStartTime = 0;
        
        document.addEventListener('touchstart', (e) => {
            if (e.touches.length === 1) {
                touchStartX = e.touches[0].clientX;
                touchStartY = e.touches[0].clientY;
                touchStartTime = Date.now();
            }
        }, { passive: true });
        
        document.addEventListener('touchend', (e) => {
            if (e.changedTouches.length === 1) {
                const touchEndX = e.changedTouches[0].clientX;
                const touchEndY = e.changedTouches[0].clientY;
                const touchEndTime = Date.now();
                
                const deltaX = touchEndX - touchStartX;
                const deltaY = touchEndY - touchStartY;
                const deltaTime = touchEndTime - touchStartTime;
                const velocity = Math.abs(deltaX) / deltaTime;
                
                // Check if this is a swipe gesture
                if (Math.abs(deltaX) > this.options.swipeThreshold &&
                    Math.abs(deltaY) < Math.abs(deltaX) &&
                    velocity > this.options.swipeVelocityThreshold) {
                    
                    const direction = deltaX > 0 ? 'right' : 'left';
                    this.handleSwipeGesture(direction, e.target);
                }
            }
        }, { passive: true });
    }
    
    /**
     * Handle swipe gestures
     */
    handleSwipeGesture(direction, target) {
        // Handle swipe on filter panels
        if (target.closest('.filter-panel')) {
            if (direction === 'down' || direction === 'up') {
                this.toggleFilterPanel();
            }
        }
        
        // Handle swipe on road trip list
        if (target.closest('.parks-list')) {
            if (direction === 'left') {
                this.showParkActions(target);
            } else if (direction === 'right') {
                this.hideParkActions(target);
            }
        }
        
        // Emit custom swipe event
        const swipeEvent = new CustomEvent('swipe', {
            detail: { direction, target }
        });
        document.dispatchEvent(swipeEvent);
    }
    
    /**
     * Setup responsive handling for orientation changes
     */
    setupResponsiveHandling() {
        if (!this.options.enableResponsiveResize) return;
        
        // Handle orientation changes
        window.addEventListener('orientationchange', () => {
            setTimeout(() => {
                this.handleOrientationChange();
            }, this.options.orientationChangeDelay);
        });
        
        // Handle window resize
        let resizeTimeout;
        window.addEventListener('resize', () => {
            clearTimeout(resizeTimeout);
            resizeTimeout = setTimeout(() => {
                this.handleWindowResize();
            }, 250);
        });
        
        // Handle viewport changes (for mobile browsers with dynamic toolbars)
        this.setupViewportHandler();
    }
    
    /**
     * Handle orientation change
     */
    handleOrientationChange() {
        const newOrientation = this.getOrientation();
        
        if (newOrientation !== this.orientation) {
            this.orientation = newOrientation;
            
            // Resize all map instances
            this.mapInstances.forEach(mapInstance => {
                if (mapInstance.invalidateSize) {
                    mapInstance.invalidateSize();
                }
            });
            
            // Emit orientation change event
            const orientationEvent = new CustomEvent('orientationChanged', {
                detail: { orientation: this.orientation }
            });
            document.dispatchEvent(orientationEvent);
        }
    }
    
    /**
     * Handle window resize
     */
    handleWindowResize() {
        // Update mobile detection
        this.isMobile = this.detectMobileDevice();
        
        // Resize map instances
        this.mapInstances.forEach(mapInstance => {
            if (mapInstance.invalidateSize) {
                mapInstance.invalidateSize();
            }
        });
        
        // Update touch targets
        this.enhanceTouchTargets();
    }
    
    /**
     * Setup viewport handler for dynamic mobile toolbars
     */
    setupViewportHandler() {
        // Use visual viewport API if available
        if (window.visualViewport) {
            window.visualViewport.addEventListener('resize', () => {
                this.handleViewportChange();
            });
        }
        
        // Fallback for older browsers
        let lastHeight = window.innerHeight;
        
        const checkViewportChange = () => {
            if (Math.abs(window.innerHeight - lastHeight) > 100) {
                lastHeight = window.innerHeight;
                this.handleViewportChange();
            }
        };
        
        window.addEventListener('resize', checkViewportChange);
        document.addEventListener('focusin', checkViewportChange);
        document.addEventListener('focusout', checkViewportChange);
    }
    
    /**
     * Handle viewport changes
     */
    handleViewportChange() {
        // Adjust map container heights
        const mapContainers = document.querySelectorAll('.map-container');
        mapContainers.forEach(container => {
            const viewportHeight = window.visualViewport ? window.visualViewport.height : window.innerHeight;
            
            if (viewportHeight < 500) {
                container.style.height = '40vh';
            } else {
                container.style.height = ''; // Reset to CSS default
            }
        });
    }
    
    /**
     * Setup battery optimization
     */
    setupBatteryOptimization() {
        if (!this.options.enableBatteryOptimization) return;
        
        // Reduce update frequency when battery is low
        if ('getBattery' in navigator) {
            navigator.getBattery().then(battery => {
                const optimizeBattery = () => {
                    if (battery.level < 0.2) { // Battery below 20%
                        this.enableBatterySaveMode();
                    } else {
                        this.disableBatterySaveMode();
                    }
                };
                
                battery.addEventListener('levelchange', optimizeBattery);
                optimizeBattery();
            });
        }
        
        // Reduce activity when page is not visible
        document.addEventListener('visibilitychange', () => {
            if (document.hidden) {
                this.pauseNonEssentialFeatures();
            } else {
                this.resumeNonEssentialFeatures();
            }
        });
    }
    
    /**
     * Enable battery save mode
     */
    enableBatterySaveMode() {
        console.log('Enabling battery save mode');
        
        // Reduce map update frequency
        this.mapInstances.forEach(mapInstance => {
            if (mapInstance.options) {
                mapInstance.options.updateInterval = 5000; // Increase to 5 seconds
            }
        });
        
        // Disable animations
        document.body.classList.add('battery-save-mode');
    }
    
    /**
     * Disable battery save mode
     */
    disableBatterySaveMode() {
        console.log('Disabling battery save mode');
        
        // Restore normal update frequency
        this.mapInstances.forEach(mapInstance => {
            if (mapInstance.options) {
                mapInstance.options.updateInterval = 1000; // Restore to 1 second
            }
        });
        
        // Re-enable animations
        document.body.classList.remove('battery-save-mode');
    }
    
    /**
     * Pause non-essential features
     */
    pauseNonEssentialFeatures() {
        // Pause location watching
        if (window.userLocation && window.userLocation.stopWatching) {
            window.userLocation.stopWatching();
        }
        
        // Reduce map updates
        this.mapInstances.forEach(mapInstance => {
            if (mapInstance.pauseUpdates) {
                mapInstance.pauseUpdates();
            }
        });
    }
    
    /**
     * Resume non-essential features
     */
    resumeNonEssentialFeatures() {
        // Resume location watching if it was active
        if (window.userLocation && window.userLocation.options.watchPosition) {
            window.userLocation.startWatching();
        }
        
        // Resume map updates
        this.mapInstances.forEach(mapInstance => {
            if (mapInstance.resumeUpdates) {
                mapInstance.resumeUpdates();
            }
        });
    }
    
    /**
     * Setup accessibility enhancements for mobile
     */
    setupAccessibilityEnhancements() {
        // Add focus indicators for touch navigation
        const focusableElements = document.querySelectorAll('button, a, input, select, textarea, [tabindex]');
        
        focusableElements.forEach(element => {
            element.addEventListener('focus', () => {
                element.classList.add('touch-focused');
            });
            
            element.addEventListener('blur', () => {
                element.classList.remove('touch-focused');
            });
        });
        
        // Enhance keyboard navigation
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Tab') {
                document.body.classList.add('keyboard-navigation');
            }
        });
        
        document.addEventListener('mousedown', () => {
            document.body.classList.remove('keyboard-navigation');
        });
    }
    
    /**
     * Bind event handlers
     */
    bindEventHandlers() {
        // Handle double-tap to zoom
        this.setupDoubleTapZoom();
        
        // Handle long press
        this.setupLongPress();
        
        // Handle pinch gestures
        if (this.options.enablePinchZoom) {
            this.setupPinchZoom();
        }
    }
    
    /**
     * Setup double-tap to zoom
     */
    setupDoubleTapZoom() {
        let lastTapTime = 0;
        
        document.addEventListener('touchend', (e) => {
            const currentTime = Date.now();
            
            if (currentTime - lastTapTime < 300) {
                // Double tap detected
                const target = e.target;
                if (target.closest('.leaflet-container')) {
                    this.handleDoubleTapZoom(e);
                }
            }
            
            lastTapTime = currentTime;
        }, { passive: true });
    }
    
    /**
     * Handle double-tap zoom
     */
    handleDoubleTapZoom(e) {
        const mapContainer = e.target.closest('.leaflet-container');
        if (!mapContainer) return;
        
        // Find associated map instance
        this.mapInstances.forEach(mapInstance => {
            if (mapInstance.getContainer() === mapContainer) {
                const currentZoom = mapInstance.getZoom();
                const newZoom = currentZoom < mapInstance.getMaxZoom() ? currentZoom + 2 : mapInstance.getMinZoom();
                
                mapInstance.setZoom(newZoom, {
                    animate: true,
                    duration: 0.3
                });
            }
        });
    }
    
    /**
     * Setup long press detection
     */
    setupLongPress() {
        let pressTimer;
        
        document.addEventListener('touchstart', (e) => {
            pressTimer = setTimeout(() => {
                this.handleLongPress(e);
            }, 750); // 750ms for long press
        }, { passive: true });
        
        document.addEventListener('touchend', () => {
            clearTimeout(pressTimer);
        }, { passive: true });
        
        document.addEventListener('touchmove', () => {
            clearTimeout(pressTimer);
        }, { passive: true });
    }
    
    /**
     * Handle long press
     */
    handleLongPress(e) {
        const target = e.target;
        
        // Emit long press event
        const longPressEvent = new CustomEvent('longPress', {
            detail: { target, touches: e.touches }
        });
        target.dispatchEvent(longPressEvent);
        
        // Provide haptic feedback if available
        if (navigator.vibrate) {
            navigator.vibrate(50);
        }
    }
    
    /**
     * Setup pinch zoom for maps
     */
    setupPinchZoom() {
        document.addEventListener('touchstart', (e) => {
            if (e.touches.length === 2) {
                this.gestureState.isActive = true;
                this.gestureState.startDistance = this.getDistance(e.touches[0], e.touches[1]);
                this.gestureState.startCenter = this.getCenter(e.touches[0], e.touches[1]);
            }
        }, { passive: true });
        
        document.addEventListener('touchmove', (e) => {
            if (this.gestureState.isActive && e.touches.length === 2) {
                this.handlePinchZoom(e);
            }
        }, { passive: false });
        
        document.addEventListener('touchend', () => {
            this.gestureState.isActive = false;
        }, { passive: true });
    }
    
    /**
     * Handle pinch zoom gesture
     */
    handlePinchZoom(e) {
        if (!e.target.closest('.leaflet-container')) return;
        
        const currentDistance = this.getDistance(e.touches[0], e.touches[1]);
        const scale = currentDistance / this.gestureState.startDistance;
        
        // Emit pinch event
        const pinchEvent = new CustomEvent('pinch', {
            detail: { scale, center: this.gestureState.startCenter }
        });
        e.target.dispatchEvent(pinchEvent);
    }
    
    /**
     * Get distance between two touch points
     */
    getDistance(touch1, touch2) {
        const dx = touch1.clientX - touch2.clientX;
        const dy = touch1.clientY - touch2.clientY;
        return Math.sqrt(dx * dx + dy * dy);
    }
    
    /**
     * Get center point between two touches
     */
    getCenter(touch1, touch2) {
        return {
            x: (touch1.clientX + touch2.clientX) / 2,
            y: (touch1.clientY + touch2.clientY) / 2
        };
    }
    
    /**
     * Register map instance for mobile optimizations
     */
    registerMapInstance(mapInstance) {
        this.mapInstances.add(mapInstance);
        
        // Apply mobile-specific map options
        if (this.isMobile && mapInstance.options) {
            mapInstance.options.zoomControl = false; // Use custom larger controls
            mapInstance.options.attributionControl = false; // Save space
        }
    }
    
    /**
     * Unregister map instance
     */
    unregisterMapInstance(mapInstance) {
        this.mapInstances.delete(mapInstance);
    }
    
    /**
     * Toggle filter panel for mobile
     */
    toggleFilterPanel() {
        const filterPanel = document.querySelector('.filter-panel');
        if (filterPanel) {
            filterPanel.classList.toggle('mobile-expanded');
        }
    }
    
    /**
     * Show park actions on swipe
     */
    showParkActions(target) {
        const parkItem = target.closest('.park-item');
        if (parkItem) {
            parkItem.classList.add('actions-visible');
        }
    }
    
    /**
     * Hide park actions
     */
    hideParkActions(target) {
        const parkItem = target.closest('.park-item');
        if (parkItem) {
            parkItem.classList.remove('actions-visible');
        }
    }
    
    /**
     * Check if device is mobile
     */
    isMobileDevice() {
        return this.isMobile;
    }
    
    /**
     * Check if device supports touch
     */
    isTouchDevice() {
        return this.isTouch;
    }
    
    /**
     * Get device info
     */
    getDeviceInfo() {
        return {
            isMobile: this.isMobile,
            isTouch: this.isTouch,
            orientation: this.orientation,
            viewportWidth: window.innerWidth,
            viewportHeight: window.innerHeight,
            pixelRatio: window.devicePixelRatio || 1
        };
    }
}

// Auto-initialize mobile touch support
document.addEventListener('DOMContentLoaded', function() {
    window.mobileTouchSupport = new MobileTouchSupport();
    
    // Register existing map instances
    if (window.thrillwikiMap) {
        window.mobileTouchSupport.registerMapInstance(window.thrillwikiMap);
    }
});

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