import 'dart:io' show Platform;
import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart';
import 'package:google_navigation_flutter/google_navigation_flutter.dart';
import '../models/delivery.dart';
import '../theme/color_system.dart';
import '../utils/toast_helper.dart';

/// Enhanced dark-mode aware map component with custom styling
class DarkModeMapComponent extends StatefulWidget {
  final List<Delivery> deliveries;
  final Delivery? selectedDelivery;
  final ValueChanged<Delivery?>? onDeliverySelected;
  final Function(String)? onAction;

  const DarkModeMapComponent({
    super.key,
    required this.deliveries,
    this.selectedDelivery,
    this.onDeliverySelected,
    this.onAction,
  });

  @override
  State<DarkModeMapComponent> createState() => _DarkModeMapComponentState();
}

class _DarkModeMapComponentState extends State<DarkModeMapComponent> {
  GoogleNavigationViewController? _navigationController;
  bool _isNavigating = false;
  LatLng? _destinationLocation;
  bool _isSessionInitialized = false;
  bool _isInitializing = false;
  bool _isStartingNavigation = false;
  String _loadingMessage = 'Initializing...';
  Brightness? _lastBrightness;
  bool _isMapViewReady = false;
  bool _isDisposed = false;

  @override
  void initState() {
    super.initState();
    _initializeNavigation();
  }

  @override
  void dispose() {
    _isDisposed = true;
    _navigationController = null;
    super.dispose();
  }

  @override
  void didUpdateWidget(DarkModeMapComponent oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.selectedDelivery != widget.selectedDelivery) {
      _updateDestination();

      // If navigation was active, restart navigation to new delivery
      if (_isNavigating &&
          widget.selectedDelivery != null &&
          widget.selectedDelivery!.deliveryAddress != null) {
        _restartNavigationToNewDelivery();
      }
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();

    // Detect theme changes and reapply map style
    final currentBrightness = Theme.of(context).brightness;
    if (_lastBrightness != null &&
        _lastBrightness != currentBrightness &&
        _navigationController != null &&
        !_isDisposed) {
      _applyDarkModeStyle();
    }
    _lastBrightness = currentBrightness;
  }

  Future<void> _restartNavigationToNewDelivery() async {
    try {
      // Stop current navigation
      await _stopNavigation();
      // Wait a bit for stop to complete
      await Future.delayed(const Duration(milliseconds: 300));
      // Start navigation to new delivery
      if (mounted && !_isDisposed) {
        await _startNavigation();
      }
    } catch (e) {
      debugPrint('Restart navigation error: $e');
    }
  }

  Future<void> _initializeNavigation() async {
    if (_isInitializing || _isSessionInitialized) return;

    setState(() {
      _isInitializing = true;
    });

    try {
      final termsAccepted = await GoogleMapsNavigator.areTermsAccepted();
      if (!termsAccepted) {
        await GoogleMapsNavigator.showTermsAndConditionsDialog(
          'Plan B Logistics',
          'com.goutezplanb.planbLogistic',
        );
      }
      await GoogleMapsNavigator.initializeNavigationSession();

      if (mounted) {
        setState(() {
          _isSessionInitialized = true;
          _isInitializing = false;
        });
      }
    } catch (e) {
      final errorMessage = _formatErrorMessage(e);
      debugPrint('Map initialization error: $errorMessage');

      if (mounted) {
        setState(() {
          _isInitializing = false;
        });

        ToastHelper.showError(context, 'Navigation initialization failed: $errorMessage');
      }
    }
  }

  String _formatErrorMessage(Object error) {
    final errorString = error.toString();
    if (errorString.contains('SessionNotInitializedException')) {
      return 'Google Maps navigation session could not be initialized';
    } else if (errorString.contains('permission')) {
      return 'Location permission is required for navigation';
    } else if (errorString.contains('network')) {
      return 'Network connection error';
    }
    return errorString;
  }

  void _updateDestination() {
    if (widget.selectedDelivery != null) {
      final address = widget.selectedDelivery!.deliveryAddress;
      if (address?.latitude != null && address?.longitude != null) {
        setState(() {
          _destinationLocation = LatLng(
            latitude: address!.latitude!,
            longitude: address.longitude!,
          );
        });
        // Just store the destination, don't move camera
        // The navigation will handle camera positioning
      }
    }
  }

  Future<void> _applyDarkModeStyle() async {
    // Check if widget is still mounted and controller exists
    if (!mounted || _navigationController == null || _isDisposed || !_isMapViewReady) return;

    try {
      if (!mounted || _isDisposed) return;

      // Force dark mode map style using Google's standard dark theme
      const String darkMapStyle = '''
      [
        {
          "elementType": "geometry",
          "stylers": [{"color": "#242f3e"}]
        },
        {
          "elementType": "labels.text.stroke",
          "stylers": [{"color": "#242f3e"}]
        },
        {
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#746855"}]
        },
        {
          "featureType": "administrative.locality",
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#d59563"}]
        },
        {
          "featureType": "poi",
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#d59563"}]
        },
        {
          "featureType": "poi.park",
          "elementType": "geometry",
          "stylers": [{"color": "#263c3f"}]
        },
        {
          "featureType": "poi.park",
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#6b9a76"}]
        },
        {
          "featureType": "road",
          "elementType": "geometry",
          "stylers": [{"color": "#38414e"}]
        },
        {
          "featureType": "road",
          "elementType": "geometry.stroke",
          "stylers": [{"color": "#212a37"}]
        },
        {
          "featureType": "road",
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#9ca5b3"}]
        },
        {
          "featureType": "road.highway",
          "elementType": "geometry",
          "stylers": [{"color": "#746855"}]
        },
        {
          "featureType": "road.highway",
          "elementType": "geometry.stroke",
          "stylers": [{"color": "#1f2835"}]
        },
        {
          "featureType": "road.highway",
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#f3d19c"}]
        },
        {
          "featureType": "transit",
          "elementType": "geometry",
          "stylers": [{"color": "#2f3948"}]
        },
        {
          "featureType": "transit.station",
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#d59563"}]
        },
        {
          "featureType": "water",
          "elementType": "geometry",
          "stylers": [{"color": "#17263c"}]
        },
        {
          "featureType": "water",
          "elementType": "labels.text.fill",
          "stylers": [{"color": "#515c6d"}]
        },
        {
          "featureType": "water",
          "elementType": "labels.text.stroke",
          "stylers": [{"color": "#17263c"}]
        }
      ]
      ''';

      await _navigationController!.setMapStyle(darkMapStyle);
      debugPrint('Dark mode map style applied');
    } catch (e) {
      if (mounted) {
        debugPrint('Error applying map style: $e');
      }
    }
  }

  Future<void> _startNavigation() async {
    if (_destinationLocation == null) return;

    // Show loading indicator
    if (mounted) {
      setState(() {
        _isStartingNavigation = true;
        _loadingMessage = 'Starting navigation...';
      });
    }

    try {
      // Ensure session is initialized before starting navigation
      if (!_isSessionInitialized && !_isInitializing) {
        debugPrint('Initializing navigation session...');
        await _initializeNavigation();
      }

      // Wait for initialization to complete if it's in progress
      int retries = 0;
      while (!_isSessionInitialized && retries < 30) {
        await Future.delayed(const Duration(milliseconds: 100));
        retries++;
      }

      if (!_isSessionInitialized) {
        if (mounted) {
          setState(() {
            _isStartingNavigation = false;
          });
          ToastHelper.showError(context, 'Navigation initialization timeout');
        }
        return;
      }

      if (mounted) {
        setState(() {
          _loadingMessage = 'Setting destination...';
        });
      }

      final waypoint = NavigationWaypoint.withLatLngTarget(
        title: widget.selectedDelivery?.name ?? 'Destination',
        target: _destinationLocation!,
      );

      final destinations = Destinations(
        waypoints: [waypoint],
        displayOptions: NavigationDisplayOptions(showDestinationMarkers: true),
      );

      if (mounted) {
        setState(() {
          _loadingMessage = 'Starting guidance...';
        });
      }

      debugPrint('Setting destinations: ${_destinationLocation!.latitude}, ${_destinationLocation!.longitude}');
      await GoogleMapsNavigator.setDestinations(destinations);

      debugPrint('Starting guidance...');
      await GoogleMapsNavigator.startGuidance();

      debugPrint('Navigation started successfully');

      // On iOS Simulator in debug mode, start simulation to provide location updates
      // The iOS Simulator doesn't provide continuous location updates for custom locations,
      // so we use the SDK's built-in simulation to simulate driving along the route.
      // This is only needed for testing on iOS Simulator - real devices work without this.
      if (kDebugMode && Platform.isIOS) {
        try {
          // Start simulating the route with a speed multiplier for testing
          // speedMultiplier: 1.0 = normal speed, 5.0 = 5x faster for quicker testing
          await GoogleMapsNavigator.simulator.simulateLocationsAlongExistingRouteWithOptions(
            SimulationOptions(speedMultiplier: 5.0),
          );
          debugPrint('Simulation started for iOS Simulator testing');
        } catch (e) {
          debugPrint('Could not start simulation: $e');
        }
      }

      // Reapply dark mode style after navigation starts
      if (mounted) {
        await _applyDarkModeStyle();
      }

      // Auto-recenter on driver location when navigation starts
      await _recenterMap();
      debugPrint('Camera recentered on driver location');

      if (mounted) {
        setState(() {
          _isNavigating = true;
          _isStartingNavigation = false;
        });
      }
    } catch (e) {
      final errorMessage = _formatErrorMessage(e);
      debugPrint('Navigation start error: $errorMessage');
      debugPrint('Full error: $e');

      if (mounted) {
        setState(() {
          _isStartingNavigation = false;
        });

        ToastHelper.showError(context, 'Navigation error: $errorMessage', duration: const Duration(seconds: 4));
      }
    }
  }

  Future<void> _stopNavigation() async {
    try {
      // Stop simulation if it was running (iOS Simulator)
      if (kDebugMode && Platform.isIOS) {
        try {
          // Remove simulated user location to stop the simulation
          await GoogleMapsNavigator.simulator.removeUserLocation();
          debugPrint('Simulation stopped');
        } catch (e) {
          debugPrint('Could not stop simulation: $e');
        }
      }

      await GoogleMapsNavigator.stopGuidance();
      await GoogleMapsNavigator.clearDestinations();
      if (mounted) {
        setState(() {
          _isNavigating = false;
        });
      }
    } catch (e) {
      if (mounted) {
        debugPrint('Navigation stop error: $e');
      }
    }
  }

  Future<void> _recenterMap() async {
    if (_navigationController == null) return;
    try {
      // Use the navigation controller's follow location feature
      // This tells the navigation to follow the driver's current location
      await _navigationController!.followMyLocation(CameraPerspective.tilted);
      debugPrint('Navigation set to follow driver location');
    } catch (e) {
      debugPrint('Recenter map error: $e');
    }
  }

  bool _hasNotes() {
    if (widget.selectedDelivery == null) return false;
    return widget.selectedDelivery!.orders.any((order) =>
      order.note != null && order.note!.isNotEmpty
    );
  }

  @override
  Widget build(BuildContext context) {
    // Driver's current location (defaults to Montreal if not available)
    final initialPosition = const LatLng(latitude: 45.5017, longitude: -73.5673);

    // Calculate dynamic padding for bottom button bar
    final topPadding = 0.0;
    final bottomPadding = 60.0;

    return Stack(
      children: [
        // Map with padding to accommodate overlaid elements
        Padding(
          padding: EdgeInsets.only(
            top: topPadding,
            bottom: bottomPadding,
          ),
          child: GoogleMapsNavigationView(
            // Enable navigation UI automatically when guidance starts
            // This is critical for iOS to display turn-by-turn directions, ETA, distance
            initialNavigationUIEnabledPreference: NavigationUIEnabledPreference.automatic,
            onViewCreated: (controller) async {
              // Early exit if widget is already disposed
              if (_isDisposed || !mounted) return;

              _navigationController = controller;

              // Wait longer for the map to be fully initialized on Android
              // This helps prevent crashes when the view is disposed during initialization
              await Future.delayed(const Duration(milliseconds: 1500));

              // Safety check: ensure widget is still mounted before proceeding
              if (!mounted || _isDisposed) {
                _navigationController = null;
                return;
              }

              // Mark map as ready only after the delay
              _isMapViewReady = true;

              // Enable navigation UI elements (header with turn directions, footer with ETA/distance)
              // This is required for iOS to show trip info, duration, and ETA
              try {
                if (!mounted || _isDisposed) return;
                await controller.setNavigationUIEnabled(true);
                if (!mounted || _isDisposed) return;
                await controller.setNavigationHeaderEnabled(true);
                if (!mounted || _isDisposed) return;
                await controller.setNavigationFooterEnabled(true);
                if (!mounted || _isDisposed) return;
                await controller.setNavigationTripProgressBarEnabled(true);
                if (!mounted || _isDisposed) return;
                // Disable report incident button
                await controller.setReportIncidentButtonEnabled(false);
                debugPrint('Navigation UI elements enabled');

                // Configure map settings to reduce GPU load for devices with limited graphics capabilities
                if (!mounted || _isDisposed) return;
                await controller.settings.setTrafficEnabled(true);
                if (!mounted || _isDisposed) return;
                await controller.settings.setRotateGesturesEnabled(true);
                if (!mounted || _isDisposed) return;
                await controller.settings.setTiltGesturesEnabled(false);
                if (!mounted || _isDisposed) return;
                debugPrint('Map settings configured for performance');
              } catch (e) {
                debugPrint('Error configuring map: $e');
                if (_isDisposed || !mounted) return;
              }

              if (!mounted || _isDisposed) return;
              await _applyDarkModeStyle();

              // Wrap camera animation in try-catch to handle "No valid view found" errors
              // This can happen on Android when the view isn't fully ready
              try {
                if (mounted && _navigationController != null && _isMapViewReady && !_isDisposed) {
                  await controller.animateCamera(
                    CameraUpdate.newLatLngZoom(initialPosition, 12),
                  );

                  // Auto-recenter to current location after initial setup
                  await Future.delayed(const Duration(milliseconds: 500));
                  if (mounted && _navigationController != null && !_isDisposed) {
                    await _recenterMap();
                    debugPrint('Auto-recentered map to current location on initialization');
                  }
                }
              } catch (e) {
                debugPrint('Camera animation error (view may not be ready): $e');
                if (_isDisposed || !mounted) return;
                // Retry once after a longer delay
                await Future.delayed(const Duration(milliseconds: 1500));
                if (mounted && _navigationController != null && _isMapViewReady && !_isDisposed) {
                  try {
                    await controller.animateCamera(
                      CameraUpdate.newLatLngZoom(initialPosition, 12),
                    );

                    // Auto-recenter to current location after retry
                    await Future.delayed(const Duration(milliseconds: 500));
                    if (mounted && _navigationController != null && !_isDisposed) {
                      await _recenterMap();
                      debugPrint('Auto-recentered map to current location on initialization (retry)');
                    }
                  } catch (e2) {
                    debugPrint('Camera animation retry failed: $e2');
                  }
                }
              }
            },
            initialCameraPosition: CameraPosition(
              target: initialPosition,
              zoom: 12,
            ),
          ),
        ),
        // Bottom action button bar - 4 equal-width buttons (always visible)
        Positioned(
            bottom: 0,
            left: 0,
            right: 0,
            child: Container(
              decoration: BoxDecoration(
                color: Theme.of(context).colorScheme.surface,
                boxShadow: [
                  BoxShadow(
                    color: Colors.black.withValues(alpha: 0.2),
                    blurRadius: 8,
                    offset: const Offset(0, -2),
                  ),
                ],
              ),
              padding: const EdgeInsets.symmetric(
                horizontal: 12,
                vertical: 8,
              ),
              child: Row(
                children: [
                  // Start button
                  Expanded(
                    child: _buildBottomActionButton(
                      label: _isNavigating ? 'Stop' : 'Start',
                      icon: _isNavigating ? Icons.stop : Icons.navigation,
                      onPressed: _isStartingNavigation || _isInitializing || (widget.selectedDelivery == null && !_isNavigating)
                          ? null
                          : (_isNavigating ? _stopNavigation : _startNavigation),
                      isDanger: _isNavigating,
                    ),
                  ),
                  const SizedBox(width: 8),
                  // Photo button (disabled when no delivery selected or warehouse delivery)
                  Expanded(
                    child: _buildBottomActionButton(
                      label: 'Photo',
                      icon: Icons.camera_alt,
                      onPressed: widget.selectedDelivery != null && !widget.selectedDelivery!.isWarehouseDelivery
                          ? () => widget.onAction?.call('photo')
                          : null,
                    ),
                  ),
                  const SizedBox(width: 8),
                  // Note button (only enabled if delivery has notes and not warehouse)
                  Expanded(
                    child: _buildBottomActionButton(
                      label: 'Note',
                      icon: Icons.note_add,
                      onPressed: _hasNotes() && widget.selectedDelivery != null && !widget.selectedDelivery!.isWarehouseDelivery
                          ? () => widget.onAction?.call('note')
                          : null,
                    ),
                  ),
                  const SizedBox(width: 8),
                  // Completed button (disabled for warehouse delivery)
                  Expanded(
                    child: _buildBottomActionButton(
                      label: widget.selectedDelivery?.delivered == true ? 'Undo' : 'Completed',
                      icon: widget.selectedDelivery?.delivered == true ? Icons.undo : Icons.check_circle,
                      onPressed: widget.selectedDelivery != null && !widget.selectedDelivery!.isWarehouseDelivery
                          ? () => widget.onAction?.call(
                                widget.selectedDelivery!.delivered ? 'uncomplete' : 'complete',
                              )
                          : null,
                      isPrimary: widget.selectedDelivery != null && !widget.selectedDelivery!.delivered && !widget.selectedDelivery!.isWarehouseDelivery,
                    ),
                  ),
                ],
              ),
            ),
          ),
        // Loading overlay during navigation initialization and start
        if (_isStartingNavigation || _isInitializing)
          Positioned.fill(
            child: Container(
              color: Colors.black.withValues(alpha: 0.4),
              child: Center(
                child: Container(
                  padding: const EdgeInsets.all(24),
                  decoration: BoxDecoration(
                    color: Theme.of(context).colorScheme.surface,
                    borderRadius: BorderRadius.circular(12),
                    boxShadow: [
                      BoxShadow(
                        color: Colors.black.withValues(alpha: 0.3),
                        blurRadius: 12,
                        offset: const Offset(0, 4),
                      ),
                    ],
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      // Circular progress indicator
                      SizedBox(
                        width: 60,
                        height: 60,
                        child: CircularProgressIndicator(
                          valueColor: AlwaysStoppedAnimation<Color>(
                            Theme.of(context).colorScheme.primary,
                          ),
                          strokeWidth: 3,
                        ),
                      ),
                      const SizedBox(height: 16),
                      // Loading message
                      Text(
                        _loadingMessage,
                        style: Theme.of(context).textTheme.titleMedium?.copyWith(
                          fontWeight: FontWeight.w600,
                        ),
                        textAlign: TextAlign.center,
                      ),
                      const SizedBox(height: 8),
                      // Secondary message
                      Text(
                        'Please wait...',
                        style: Theme.of(context).textTheme.bodySmall?.copyWith(
                          color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
                        ),
                        textAlign: TextAlign.center,
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
      ],
    );
  }

  Widget _buildBottomActionButton({
    required String label,
    required IconData icon,
    required VoidCallback? onPressed,
    bool isPrimary = false,
    bool isDanger = false,
  }) {
    Color backgroundColor;
    Color textColor = Colors.white;

    if (isDanger) {
      backgroundColor = SvrntyColors.crimsonRed;
    } else if (isPrimary) {
      backgroundColor = SvrntyColors.crimsonRed;
    } else {
      // Use the same slateGray as delivery list badges
      backgroundColor = SvrntyColors.slateGray;
    }

    // Reduce opacity when disabled
    if (onPressed == null) {
      backgroundColor = backgroundColor.withValues(alpha: 0.5);
    }

    return Material(
      color: backgroundColor,
      borderRadius: BorderRadius.circular(6),
      child: InkWell(
        onTap: onPressed,
        borderRadius: BorderRadius.circular(6),
        child: Padding(
          padding: const EdgeInsets.symmetric(
            horizontal: 8,
            vertical: 10,
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(
                icon,
                color: textColor,
                size: 18,
              ),
              const SizedBox(width: 6),
              Text(
                label,
                style: TextStyle(
                  color: textColor,
                  fontWeight: FontWeight.w600,
                  fontSize: 14,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }

}
