import React, { useEffect, useRef, useState, useCallback, useMemo } from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
import ArrowIcon from './ArrowIcon';
import ReactDOM from 'react-dom/client';
import { createClient } from '../../lib/supabase/client';
import { toast } from "@/components/ui/use-toast";

interface RouteInfo {
  route_id: string; // Assuming these might be part of the route object
  route_short_name: string;
  type?: string; // For the image, e.g., 'bus', 'subway'
  // Add any other relevant properties from the actual route object structure
}

interface Stop {
  stop_id: string;
  stop_name: string;
  lat: number;
  lng: number;
  routes?: RouteInfo[]; // Changed from string[]
  current_stop?: boolean;
}

interface Direction {
  route_id: string;
  direction_id: number;
  stop_ids: string[];
}

// Add new interface for chevron marker
interface ChevronMarker {
  marker: mapboxgl.Marker;
  element: HTMLDivElement;
}

interface StopsMapModalProps {
  isOpen: boolean;
  onClose: () => void;
  stops: Stop[];
  routeName: string;
  game: {
    id: string;
  };
  directions?: Direction[];
  onNavigate?: (lat: number, lng: number) => void;
  endLat?: number;
  endLng?: number;
  onGameEnd?: (score: number, duration: string) => void;
}

mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN || '';

// Add custom CSS for the popup
const popupStyles = `
  .stop-popup .mapboxgl-popup-close-button {
    font-size: 20px;
    color: #666;
    background: white;
    border-radius: 50%;
    width: 24px;
    height: 24px;
    line-height: 20px;
    text-align: center;
    padding: 0;
    margin: 8px 8px 0 0;
    border: none;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  }

  .stop-popup .mapboxgl-popup-close-button:hover {
    background: #f0f0f0;
    color: #333;
  }

  .stop-popup .mapboxgl-popup-content {
    padding: 15px;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
  }

  .stop-popup .mapboxgl-popup-tip {
    border-top-color: white !important;
  }
`;

const StopsMapModal: React.FC<StopsMapModalProps> = ({ isOpen, onClose, stops, routeName, game, directions, onNavigate, endLat, endLng }) => {
  // Log all props when component renders

  // If directions exist, log details about them
  if (directions && directions.length > 0) {
    console.log("Directions details:", directions.map(dir => ({
      directionId: dir.direction_id,
      routeId: dir.route_id,
      stopCount: dir.stop_ids.length,
      firstStop: dir.stop_ids[0],
      lastStop: dir.stop_ids[dir.stop_ids.length - 1]
    })));
  }

  const mapContainer = useRef<HTMLDivElement>(null);
  const mapRef = useRef<mapboxgl.Map | null>(null);
  const popupRef = useRef<mapboxgl.Popup | null>(null);
  const chevronMarkerRef = useRef<ChevronMarker | null>(null);
  const [selectedDirection, setSelectedDirection] = useState<number | undefined>(undefined);
  const firstStopMarkerRef = useRef<mapboxgl.Marker | null>(null);
  const firstStopMarkerDivRef = useRef<HTMLDivElement | null>(null);
  const firstStopArrowRootRef = useRef<ReturnType<typeof ReactDOM.createRoot> | null>(null);
  const [showBoardOptions, setShowBoardOptions] = useState(false);
  const [currentStopIndex, setCurrentStopIndex] = useState<number>(0);
  const [isBoarded, setIsBoarded] = useState(false);
  const [firstStopIndex, setFirstStopIndex] = useState<number>(0);
  const [activelyViewedStopId, setActivelyViewedStopId] = useState<string | null>(null);
  const [isAnimating, setIsAnimating] = useState(false);

  // Refs for the end point marker
  const endMarkerRef = useRef<mapboxgl.Marker | null>(null);
  const endMarkerDivRef = useRef<HTMLDivElement | null>(null);
  const endMarkerArrowRootRef = useRef<ReturnType<typeof ReactDOM.createRoot> | null>(null);

  const supabase = createClient();

  async function isCurrentStop(stopId: string, initialStopId: string){
    const stopInfo = stops.find(stop => stop.stop_id === stopId);
    const initialStopInfo = stops.find(stop => stop.stop_id === initialStopId);
    if (stopInfo && initialStopInfo) {
      return stopInfo.stop_name === initialStopInfo.stop_name;
    }
    return false;
  }
  // Reset state when the modal is opened with new stops or directions
  useEffect(() => {
    if (isOpen) {
      console.log("Modal opened, resetting state", { stops, directions });
      // Reset state values to defaults
      setSelectedDirection(undefined);
      setShowBoardOptions(false);
      setCurrentStopIndex(0);
      setIsBoarded(false);
      setFirstStopIndex(0);
      setActivelyViewedStopId(null);
      setIsAnimating(false);
      
      // Check if there's a current stop and set activelyViewedStopId immediately
      const initialCurrentStop = stops.find(stop => stop.current_stop);
      if (initialCurrentStop) {
        console.log("Found initial current stop", initialCurrentStop);
        setActivelyViewedStopId(initialCurrentStop.stop_id);
      }
      
      // Clean up any animated line source that might be left over
      if (mapRef.current) {
        try {
          if (mapRef.current.getLayer('animated-line-layer')) {
            mapRef.current.removeLayer('animated-line-layer');
          }
          if (mapRef.current.getSource('animated-line')) {
            mapRef.current.removeSource('animated-line');
          }
        } catch (e) {
          console.error("Error cleaning up animated line:", e);
        }
      }
      
      // Force re-evaluation of available directions when modal reopens
      // This will trigger the useEffect that depends on availableDirections
      if (directions && directions.length > 0) {
        const newAvailableDirections = directions.filter(dir => {
          const currentStop = stops.find(stop => stop.current_stop);
          if (!currentStop) return false;
          
          return dir.stop_ids.some(stopId => {
            const stopInDirection = stops.find(stop => stop.stop_id === stopId);
            return stopInDirection?.stop_name === currentStop.stop_name;
          }) && dir.stop_ids[dir.stop_ids.length - 1] !== currentStop?.stop_id;
        });
        
        console.log("Available directions on modal open:", newAvailableDirections);
        
        if (newAvailableDirections.length > 0) {
          setSelectedDirection(newAvailableDirections[0].direction_id);
        } else {
          setSelectedDirection(undefined);
        }
      }
    }
  }, [isOpen, stops, routeName, directions]);

  // Add styles to document
  useEffect(() => {
    const styleElement = document.createElement('style');
    styleElement.textContent = popupStyles;
    document.head.appendChild(styleElement);

    return () => {
      document.head.removeChild(styleElement);
    };
  }, []);

  // Add function to calculate bearing between two points
  const calculateBearing = useCallback((start: [number, number], end: [number, number]): number => {
    const startLng = start[0] * Math.PI / 180;
    const startLat = start[1] * Math.PI / 180;
    const endLng = end[0] * Math.PI / 180;
    const endLat = end[1] * Math.PI / 180;

    const y = Math.sin(endLng - startLng) * Math.cos(endLat);
    const x = Math.cos(startLat) * Math.sin(endLat) -
              Math.sin(startLat) * Math.cos(endLat) * Math.cos(endLng - startLng);
    let bearing = Math.atan2(y, x) * 180 / Math.PI;
    return (bearing + 360) % 360;
  }, []);

  // Add function to update chevron marker
  const updateChevronMarker = useCallback((currentStop: Stop, nextStop: Stop | undefined) => {
    console.log("Updating chevron marker", { currentStop, nextStop });
    if (!mapRef.current) return;

    // Remove existing chevron marker if it exists
    if (chevronMarkerRef.current) {
      try {
        chevronMarkerRef.current.marker.remove();
      } catch (error) {
        console.error("Error removing existing chevron marker:", error);
      }
      chevronMarkerRef.current = null;
    }
    
    // Calculate bearing
    let bearing = 0;
    if (nextStop) {
      bearing = calculateBearing(
        [currentStop.lng, currentStop.lat],
        [nextStop.lng, nextStop.lat]
      );
      console.log("Calculated bearing between stops:", bearing);
    }

    const EFFECTIVE_BUS_PIN_HEIGHT_PX = 51.2; // Based on 256px image * 0.2 icon-size
    const CHEVRON_SIZE_PX = 30; // As styled
    const GAP_PX = 5;

    const radius = (EFFECTIVE_BUS_PIN_HEIGHT_PX / 2) + (CHEVRON_SIZE_PX / 2) + GAP_PX;
    const bearingRad = bearing * Math.PI / 180;

    // Calculate translation for the marker element
    // translateX positions chevron horizontally relative to bus pin center
    const translateX = radius * Math.sin(bearingRad);
    // translateY accounts for bus pin's anchor and then positions chevron vertically relative to bus pin center
    const translateY = -(EFFECTIVE_BUS_PIN_HEIGHT_PX / 2) - (radius * Math.cos(bearingRad));

    // Outer element for Mapbox to handle, now with translation
    const markerElement = document.createElement('div');
    markerElement.style.width = `${CHEVRON_SIZE_PX}px`;
    markerElement.style.height = `${CHEVRON_SIZE_PX}px`;
    markerElement.style.transform = `translate(${translateX.toFixed(2)}px, ${translateY.toFixed(2)}px)`;
    // For debugging positioning:
    // markerElement.style.border = '1px dashed red';


    // Inner element for rotation and image
    const rotatingChevron = document.createElement('div');
    rotatingChevron.style.width = '50px';
    rotatingChevron.style.height = '50px';
    rotatingChevron.style.backgroundImage = 'url("https://axukvwsddnrihsfilobo.supabase.co/storage/v1/object/public/goquest//chevron2.png")';
    rotatingChevron.style.backgroundSize = 'contain';
    rotatingChevron.style.backgroundRepeat = 'no-repeat';
    rotatingChevron.style.backgroundPosition = 'center';
    rotatingChevron.style.transformOrigin = '50% 50%';
    rotatingChevron.style.transform = `rotate(${Math.round(bearing)}deg)`;
    // For debugging rotation:
    // rotatingChevron.style.border = '1px solid blue';
    markerElement.appendChild(rotatingChevron);

    // Create and add marker
    const marker = new mapboxgl.Marker({
      element: markerElement,
      anchor: 'bottom',
      rotationAlignment: 'viewport' // Changed to viewport for screen-relative positioning and rotation
    })
      .setLngLat([currentStop.lng, currentStop.lat])
      .addTo(mapRef.current);

    chevronMarkerRef.current = { marker, element: markerElement };
  }, [calculateBearing]);

  // Initialize map
  useEffect(() => {
    if (!isOpen || !mapContainer.current) return;

    console.log("Initializing map", { stops: stops.length });

    // Cleanup previous map instance if it exists
    if (mapRef.current) {
      mapRef.current.remove();
      mapRef.current = null;
    }

    // Clean up any existing chevron marker
    if (chevronMarkerRef.current) {
      chevronMarkerRef.current.marker.remove();
      chevronMarkerRef.current = null;
    }

    // Initialize new map
    const map = new mapboxgl.Map({
      container: mapContainer.current,
      style: 'mapbox://styles/mapbox/streets-v11',
      center: stops.length > 0 ? [stops[0].lng, stops[0].lat] : [0, 0],
      zoom: 15,
      interactive: true,
      bearing: 0,
    });

    map.on('load', () => {
      console.log("Map loaded");
      // Load all required images first
      const loadImages = async () => {
        try {
          // Load bus icon
          await new Promise((resolve, reject) => {
            map.loadImage('https://axukvwsddnrihsfilobo.supabase.co/storage/v1/object/public/goquest//bus.png', (error, image) => {
              if (error) reject(error);
              if (!map.hasImage('bus-pin')) {
                map.addImage('bus-pin', image!);
              }
              resolve(null);
            });
          });

          // Load arrow icon
          await new Promise((resolve, reject) => {
            map.loadImage('https://axukvwsddnrihsfilobo.supabase.co/storage/v1/object/public/goquest//bus-green.png', (error, image) => {
              if (error) reject(error);
              if (!map.hasImage('arrow-pin')) {
                map.addImage('arrow-pin', image!);
              }
              resolve(null);
            });
          });

          // Add stops data source
          map.addSource('stops', {
            type: 'geojson',
            data: {
              type: 'FeatureCollection',
              features: []
            }
          });

          // Add route line source
          map.addSource('route-line', {
            type: 'geojson',
            data: {
              type: 'Feature',
              properties: {},
              geometry: {
                type: 'LineString',
                coordinates: []
              }
            }
          });

          // Add route line layer FIRST (so it appears behind stops)
          map.addLayer({
            id: 'route-line-layer',
            type: 'line',
            source: 'route-line',
            layout: {
              'line-join': 'round',
              'line-cap': 'round'
            },
            paint: {
              'line-color': '#007bff',
              'line-width': 4,
              'line-opacity': 0.8
            }
          });

          // Add stops layer AFTER the line layer
          map.addLayer({
            id: 'other-stops-layer',
            type: 'symbol',
            source: 'stops',
            filter: ['!', ['get', 'is_first_stop']],
            layout: {
              'icon-image': 'bus-pin',
              'icon-size': 0.15,
              'icon-allow-overlap': true,
              'icon-anchor': 'bottom'
            }
          });

          // Add first stop layer after all images are loaded
          map.addLayer({
            id: 'first-stop-layer',
            type: 'symbol',
            source: 'stops',
            filter: ['get', 'is_first_stop'],
            layout: {
              'icon-image': 'arrow-pin',
              'icon-size': 0.2,
              'icon-allow-overlap': true,
              'icon-anchor': 'bottom'
            }
          });
          let newSelectedDirection = selectedDirection;
          const goodDirections = directions?.filter(d => hasCurrentStop(d)) || [];
          console.log("Good directions after map load:", goodDirections);
          if(goodDirections.length == 1){
            setSelectedDirection(goodDirections[0].direction_id);
            newSelectedDirection = goodDirections[0].direction_id;
          }
          // Initialize route line and stops for the default direction
          if (goodDirections && goodDirections.length > 0) {
            const currentDirection = goodDirections.find(d => d.direction_id === newSelectedDirection);
            if (currentDirection) {
              const orderedStops = currentDirection.stop_ids
                .map(stopId => stops.find(stop => stop.stop_id === stopId))
                .filter((stop): stop is Stop => stop !== undefined);

              console.log("Ordered stops for initial direction:", orderedStops.length);

              // Find the index of current stop
              const initialCurrentStop = stops.find(stop => stop.current_stop);
              const currentStopIndex = orderedStops.findIndex(stop => stop.stop_name === initialCurrentStop?.stop_name);
              console.log("Initial current stop index:", currentStopIndex);
              setFirstStopIndex(currentStopIndex);
              setCurrentStopIndex(currentStopIndex);
              if (initialCurrentStop) {
                setActivelyViewedStopId(initialCurrentStop.stop_id);
              }
              // When initializing, show ONLY the current stop
              const filteredStops = currentStopIndex !== -1
                ? [orderedStops[currentStopIndex]]
                : orderedStops.slice(0, 1);
              
              // Update chevron marker
              if (initialCurrentStop && filteredStops.length > 0 && currentStopIndex !== -1 && orderedStops[currentStopIndex]) {
                const nextStop = orderedStops[currentStopIndex + 1];
                updateChevronMarker(orderedStops[currentStopIndex], nextStop);
              }

              // Update stops data source
              (map.getSource('stops') as mapboxgl.GeoJSONSource).setData({
                type: 'FeatureCollection',
                features: filteredStops.map(stop => ({
                  type: 'Feature',
                  geometry: {
                    type: 'Point',
                    coordinates: [stop.lng, stop.lat]
                  },
                  properties: {
                    stop_id: stop.stop_id,
                    stop_name: stop.stop_name,
                    routes: stop.routes,
                    is_first_stop: stop.current_stop || stops.find(s => s.current_stop)?.stop_name === stop.stop_name
                  }
                }))
              });

              // Update route line
              const coordinates = filteredStops.map(stop => [stop.lng, stop.lat]);
              (map.getSource('route-line') as mapboxgl.GeoJSONSource).setData({
                type: 'Feature',
                properties: {},
                geometry: {
                  type: 'LineString',
                  coordinates: coordinates
                }
              });

              // Center map on current stop
              if (initialCurrentStop && currentStopIndex !== -1) {
                map.setCenter([initialCurrentStop.lng, initialCurrentStop.lat]);
              }
            }
          }

          // Create popup with improved styling
          const popup = new mapboxgl.Popup({
            closeButton: true,
            closeOnClick: false,
            offset: 25,
            className: 'stop-popup',
            maxWidth: '300px'
          });

          // Add click handler for stops
          map.on('click', 'other-stops-layer', (e) => {
            if (e.features && e.features.length > 0) {
              const feature = e.features[0];
              const stopId = feature.properties?.stop_id;
              const stop = stops.find(s => s.stop_id === stopId);
              
              if (stop) {
                const coordinates: [number, number] = [stop.lng, stop.lat];
                
                // Create popup content
                const popupContent = document.createElement('div');
                popupContent.style.padding = '15px';
                popupContent.style.minWidth = '200px';
                
                // Add stop name
                const nameDiv = document.createElement('div');
                nameDiv.style.fontWeight = 'bold';
                nameDiv.style.marginBottom = '8px';
                nameDiv.textContent = stop.stop_name;
                popupContent.appendChild(nameDiv);
                
                // Add coordinates
                const coordsDiv = document.createElement('div');
                coordsDiv.style.marginBottom = '8px';
                coordsDiv.textContent = `Coordinates: ${stop.lat.toFixed(6)}, ${stop.lng.toFixed(6)}`;
                popupContent.appendChild(coordsDiv);
                
                // Add routes if available
                if (stop.routes && stop.routes.length > 0) {
                  const routesDiv = document.createElement('div');
                  routesDiv.style.marginBottom = '12px';
                  routesDiv.innerHTML = `<strong>Connected Routes:</strong><br/>${stop.routes.map((route: any) => route.route_short_name).filter((route: any) => route !== routeName).join(', ')}`;
                  popupContent.appendChild(routesDiv);
                }

                // Add navigation button
                if (onNavigate) {
                  const navButton = document.createElement('button');
                  navButton.textContent = 'Navigate Here';
                  navButton.style.cssText = `
                    background-color: #007bff;
                    color: white;
                    border: none;
                    padding: 8px 16px;
                    border-radius: 4px;
                    cursor: pointer;
                    width: 100%;
                    font-weight: 500;
                  `;
                  navButton.onmouseover = () => {
                    navButton.style.backgroundColor = '#0056b3';
                  };
                  navButton.onmouseout = () => {
                    navButton.style.backgroundColor = '#007bff';
                  };
                  navButton.onclick = () => {
                    popup.remove();
                    onNavigate(stop.lat, stop.lng);
                  };
                  popupContent.appendChild(navButton);
                }
                
                // Set popup content and show it
                popup.setLngLat(coordinates)
                  .setDOMContent(popupContent)
                  .addTo(map);
                
                popupRef.current = popup;
              }
            }
          });

          // Change cursor on hover
          map.on('mouseenter', 'other-stops-layer', () => {
            map.getCanvas().style.cursor = 'pointer';
          });
          map.on('mouseleave', 'other-stops-layer', () => {
            map.getCanvas().style.cursor = '';
          });
        } catch (error) {
          console.error('Error loading map resources:', error);
        }
      };

      loadImages();
    });

    mapRef.current = map;

    // Cleanup
    return () => {
      console.log("Cleaning up map and markers");
      if (firstStopArrowRootRef.current) {
        const rootToUnmount = firstStopArrowRootRef.current;
        queueMicrotask(() => {
          rootToUnmount.unmount();
        });
        firstStopArrowRootRef.current = null;
      }
      if (firstStopMarkerRef.current) {
        firstStopMarkerRef.current.remove();
        firstStopMarkerRef.current = null;
      }
      if (popupRef.current) {
        popupRef.current.remove();
      }
      // Cleanup for end marker
      if (endMarkerArrowRootRef.current) {
        const rootToUnmount = endMarkerArrowRootRef.current;
        queueMicrotask(() => {
          rootToUnmount.unmount();
        });
        endMarkerArrowRootRef.current = null;
      }
      if (endMarkerRef.current) {
        endMarkerRef.current.remove();
        endMarkerRef.current = null;
      }
      if (mapRef.current) {
        mapRef.current.remove();
        mapRef.current = null;
      }
    };
  }, [isOpen, stops]);

  // Add end point marker when coordinates are available
  useEffect(() => {
    const currentMap = mapRef.current;
    if (!currentMap || !isOpen) return; // Also ensure map is open

    console.log("Setting up end marker", { endLat, endLng });

    // Cleanup previous end marker if it exists
    if (endMarkerRef.current) {
      if (endMarkerArrowRootRef.current) {
        const rootToUnmount = endMarkerArrowRootRef.current;
        queueMicrotask(() => {
          rootToUnmount.unmount();
        });
        endMarkerArrowRootRef.current = null;
      }
      endMarkerRef.current.remove();
      endMarkerRef.current = null;
    }
    if (endLat === undefined || endLng === undefined) {
      return; // Don't add marker if coords are not provided
    }
    
    const newEndMarkerDiv = document.createElement('div');
    newEndMarkerDiv.style.width = '40px';
    newEndMarkerDiv.style.height = '40px';
    newEndMarkerDiv.style.position = 'relative';
    newEndMarkerDiv.style.display = 'flex';
    newEndMarkerDiv.style.alignItems = 'center';
    newEndMarkerDiv.style.justifyContent = 'center';
    
    const endArrowContainer = document.createElement('div');
    endArrowContainer.style.position = 'absolute';
    endArrowContainer.style.top = '4px';
    endArrowContainer.style.left = '4px';
    endArrowContainer.style.zIndex = '2';
    endArrowContainer.style.pointerEvents = 'none';
    newEndMarkerDiv.appendChild(endArrowContainer);

    // Create a new root for the end marker's icon
    endMarkerArrowRootRef.current = ReactDOM.createRoot(endArrowContainer);
    endMarkerArrowRootRef.current.render(<ArrowIcon color="red" />); // Using red for the end point
    
    endMarkerDivRef.current = newEndMarkerDiv;
    const newEndMarker = new mapboxgl.Marker({
        element: newEndMarkerDiv,
        anchor: 'bottom',
    })
      .setLngLat([endLng, endLat])
      .addTo(currentMap);
    endMarkerRef.current = newEndMarker;

    // No explicit cleanup function here, as the main useEffect cleanup handles it
    // based on isOpen. If endLat/endLng change while modal is open, this effect re-runs.
  }, [isOpen, endLat, endLng, mapRef]); // Re-run if isOpen, endLat, endLng, or mapRef changes

  // Check if direction has current stop
  const hasCurrentStop = useCallback((direction: Direction) => {
    const currentStop = stops.find(stop => stop.current_stop);
    if (!currentStop) return false;
    
    const result = direction.stop_ids.some(stopId => {
      const stopInDirection = stops.find(stop => stop.stop_id === stopId);
      return stopInDirection?.stop_name === currentStop.stop_name;
    }) && direction.stop_ids[direction.stop_ids.length - 1] !== currentStop?.stop_id;
    
    return result;
  }, [stops]);

  // Add new function to check if current stop is last in direction
  const isCurrentStopLastInDirection = (direction: Direction) => {
    const currentStop = direction.stop_ids[currentStopIndex];
    const isLast = currentStop && direction.stop_ids[direction.stop_ids.length - 1] === currentStop;
    return isLast;
  };

  // Get available directions
  const availableDirections = useMemo(() => {
    const result = directions?.filter(dir => hasCurrentStop(dir)) || [];
    console.log("Calculated available directions:", result);
    return result;
  }, [directions, hasCurrentStop]);

  // Add function to get next available direction
  const getNextAvailableDirection = () => {
    if (!directions || !selectedDirection) return undefined;
    const currentDirectionIndex = directions.findIndex(d => d.direction_id === selectedDirection);
    const nextDirection = directions[(currentDirectionIndex + 1) % directions.length];
    const hasNext = hasCurrentStop(nextDirection);

    return hasNext ? nextDirection : undefined;
  };

  // Set initial direction to first available one, or update if current selected is not available/becomes unavailable
  useEffect(() => {
    if (isOpen && availableDirections.length > 0) {
      const isSelectedDirectionCurrentlyAvailable = availableDirections.some(d => d.direction_id === selectedDirection);
      console.log("Direction selection check", { 
        selectedDirection, 
        availableDirections: availableDirections.length,
        isSelectedDirectionCurrentlyAvailable
      });
      
      // Set if no direction is selected yet, or if the current one is no longer available
      if (selectedDirection === undefined || !isSelectedDirectionCurrentlyAvailable) {
        console.log("Setting direction to first available:", availableDirections[0].direction_id);
        setSelectedDirection(availableDirections[0].direction_id);
      }
    } else if (selectedDirection !== undefined && isOpen && availableDirections.length === 0) { 
      // No available directions
      console.log("No available directions, clearing selection");
      setSelectedDirection(undefined); // Clear selection
    }
  }, [availableDirections, selectedDirection, isOpen, routeName]); // Added routeName dependency

  // Handle direction change
  const handleDirectionChange = (directionId: number) => {
    console.log("Direction changed to:", directionId);
    setSelectedDirection(directionId);
  };

  // Update route line when direction changes
  useEffect(() => {
    if (!mapRef.current || !directions || !isOpen) { // Added isOpen check
        // If mapRef or directions are not ready, can't do much yet.
        return;
    }

    console.log("Updating route line for direction", { 
      selectedDirection, 
      isBoarded,
      directions: directions?.length
    });

    if (selectedDirection === undefined) {
      // Clear map features if no direction is selected
      console.log("No direction selected, clearing map");
      if (mapRef.current.getSource('stops')) {
        (mapRef.current.getSource('stops') as mapboxgl.GeoJSONSource).setData({
          type: 'FeatureCollection',
          features: []
        });
      }
      if (mapRef.current.getSource('route-line')) {
        (mapRef.current.getSource('route-line') as mapboxgl.GeoJSONSource).setData({
          type: 'Feature',
          properties: {},
          geometry: { type: 'LineString', coordinates: [] }
        });
      }
      if (chevronMarkerRef.current) {
        chevronMarkerRef.current.marker.remove();
        chevronMarkerRef.current = null;
      }
      return;
    }
    
    // Ensure directions has length now that selectedDirection is defined.
    if (directions.length === 0) return;

    const currentDirection = directions.find(d => d.direction_id === selectedDirection);
    if (!currentDirection) return;

    // Get ordered stops for the current direction
    const orderedStops = currentDirection.stop_ids
      .map(stopId => stops.find(stop => stop.stop_id === stopId))
      .filter((stop): stop is Stop => stop !== undefined);
      
    console.log("All stops in current direction:", orderedStops.map(s => ({
      id: s.stop_id,
      name: s.stop_name,
      current: s.current_stop
    })));

    // Find the index of current stop
    const initialCurrentStop = stops.find(stop => stop.current_stop);
    const currentStopIndexInDirection = orderedStops.findIndex(stop => stop.stop_name === initialCurrentStop?.stop_name);
    
    console.log("Current stop lookup:", {
      initialCurrentStop: initialCurrentStop?.stop_name,
      foundAtIndex: currentStopIndexInDirection
    });
    
    setFirstStopIndex(currentStopIndexInDirection >= 0 ? currentStopIndexInDirection : 0);
    setCurrentStopIndex(currentStopIndexInDirection >= 0 ? currentStopIndexInDirection : 0);

    // When boarding, show stops from boarding point to current stop
    // Otherwise just show the current stop only
    const filteredStops = isBoarded 
      ? (currentStopIndexInDirection !== -1 
          ? orderedStops.slice(firstStopIndex, currentStopIndexInDirection + 1) 
          : [orderedStops[0]])
      : (currentStopIndexInDirection !== -1 
          ? [orderedStops[currentStopIndexInDirection]] 
          : [orderedStops[0]]);
          
    console.log("Filtered stops for display:", {
      isBoarded,
      firstStopIndex,
      currentStopIndex: currentStopIndexInDirection,
      stopCount: filteredStops.length,
      stops: filteredStops.map(s => s.stop_name)
    });

    // Update chevron marker for the new direction
    if (initialCurrentStop && currentStopIndexInDirection !== -1) {
      const nextStopForChevron = orderedStops[currentStopIndexInDirection + 1]; // Can be undefined
      updateChevronMarker(orderedStops[currentStopIndexInDirection], nextStopForChevron);
    } else if (chevronMarkerRef.current) {
      // If no initialCurrentStop or it's not in the new direction, remove existing chevron
      chevronMarkerRef.current.marker.remove();
      chevronMarkerRef.current = null;
    }

    // Update stops data source
    if (mapRef.current.getSource('stops')) {
      console.log("Updating map with filtered stops:", filteredStops.length);
      (mapRef.current.getSource('stops') as mapboxgl.GeoJSONSource).setData({
        type: 'FeatureCollection',
        features: filteredStops.map(stop => ({
          type: 'Feature',
          geometry: {
            type: 'Point',
            coordinates: [stop.lng, stop.lat]
          },
          properties: {
            stop_id: stop.stop_id,
            stop_name: stop.stop_name,
            routes: stop.routes,
            is_first_stop: stop.current_stop || stops.find(s => s.current_stop)?.stop_name === stop.stop_name
          }
        }))
      });
    }

    // Update route line
    if (mapRef.current.getSource('route-line')) {
      const coordinates = filteredStops.map(stop => [stop.lng, stop.lat]);
      
      console.log("Updating route line with coordinates:", coordinates.length);
      
      (mapRef.current.getSource('route-line') as mapboxgl.GeoJSONSource).setData({
        type: 'Feature',
        properties: {},
        geometry: {
          type: 'LineString',
          coordinates: coordinates
        }
      });

      // Center map on current stop
      if (initialCurrentStop) {
        mapRef.current.setCenter([initialCurrentStop.lng, initialCurrentStop.lat]);
      }
    }
  }, [selectedDirection, directions, stops, updateChevronMarker, isOpen, isBoarded]); // Added isBoarded dependency

  // Add new function for line animation
  const animateLine = useCallback((startPoint: [number, number], endPoint: [number, number], duration: number = 1000) => {
    if (!mapRef.current) return;
    
    console.log("Starting line animation", { startPoint, endPoint, duration });
    setIsAnimating(true);
    
    // Create a line source for animation
    if (!mapRef.current.getSource('animated-line')) {
      mapRef.current.addSource('animated-line', {
        type: 'geojson',
        data: {
          type: 'Feature',
          properties: {},
          geometry: {
            type: 'LineString',
            coordinates: [startPoint, startPoint] // Start with just the start point
          }
        }
      });

      mapRef.current.addLayer({
        id: 'animated-line-layer',
        type: 'line',
        source: 'animated-line',
        layout: {
          'line-join': 'round',
          'line-cap': 'round'
        },
        paint: {
          'line-color': '#007bff',
          'line-width': 4,
          'line-opacity': 0.8
        }
      });
    }

    const startTime = Date.now();
    const animate = () => {
      const elapsed = Date.now() - startTime;
      const progress = Math.min(elapsed / duration, 1);
      
      // Calculate the intermediate point
      const intermediatePoint: [number, number] = [
        startPoint[0] + (endPoint[0] - startPoint[0]) * progress,
        startPoint[1] + (endPoint[1] - startPoint[1]) * progress
      ];

      // Update the animated line
      (mapRef.current?.getSource('animated-line') as mapboxgl.GeoJSONSource)?.setData({
        type: 'Feature',
        properties: {},
        geometry: {
          type: 'LineString',
          coordinates: [startPoint, intermediatePoint]
        }
      });

      // Smoothly move the map center along with the line
      mapRef.current?.easeTo({
        center: intermediatePoint,
        duration: 0, // No duration for smooth animation
        essential: true
      });

      if (progress < 1) {
        requestAnimationFrame(animate);
      } else {
        // Animation complete, but keep isAnimating true until markers are updated
      }
    };

    requestAnimationFrame(animate);
  }, []);

  const handleBoardBus = () => {
    console.log("Boarding bus");
    setShowBoardOptions(true);
    setIsBoarded(true);
    
    // Refresh the map with filtered stops once boarding
    if (mapRef.current && selectedDirection !== undefined) {
      const currentDirection = directions?.find(d => d.direction_id === selectedDirection);
      if (currentDirection) {
        const orderedStops = currentDirection.stop_ids
          .map(stopId => stops.find(stop => stop.stop_id === stopId))
          .filter((stop): stop is Stop => stop !== undefined);
        
        console.log("Ordered stops for boarding:", {
          totalStops: orderedStops.length,
          firstStopIndex,
          currentStopIndex
        });
        
        // Now that we're boarded, filter stops to show from boarding point to current stop
        const filteredStops = orderedStops.slice(firstStopIndex, currentStopIndex + 1);
        
        console.log("Filtered stops after boarding:", {
          count: filteredStops.length,
          stops: filteredStops.map(s => s.stop_name)
        });
        
        // Update stops data source to show only from boarding point to current stop
        if (mapRef.current.getSource('stops')) {
          const initialCurrentStop = stops.find(stop => stop.current_stop);
          (mapRef.current.getSource('stops') as mapboxgl.GeoJSONSource).setData({
            type: 'FeatureCollection',
            features: filteredStops.map(stop => ({
              type: 'Feature',
              geometry: {
                type: 'Point',
                coordinates: [stop.lng, stop.lat]
              },
              properties: {
                stop_id: stop.stop_id,
                stop_name: stop.stop_name,
                routes: stop.routes,
                is_first_stop: stop.current_stop || stops.find(s => s.current_stop)?.stop_name === stop.stop_name
              }
            }))
          });
          
          // Update route line
          if (mapRef.current.getSource('route-line')) {
            const coordinates = filteredStops.map(stop => [stop.lng, stop.lat]);
            console.log("Updating route line after boarding with coordinates:", coordinates.length);
            (mapRef.current.getSource('route-line') as mapboxgl.GeoJSONSource).setData({
              type: 'Feature',
              properties: {},
              geometry: {
                type: 'LineString',
                coordinates: coordinates
              }
            });
          }
        }
      }
    }
  };

  const handleGetOff = async () => {
    const currentDirection = directions?.find(d => d.direction_id === selectedDirection);
    const currentStop = currentDirection?.stop_ids[currentStopIndex];
    const stopOverallIndex = stops.findIndex(s => s.stop_id === currentStop);
    
    console.log("Getting off at stop", { 
      currentStopIndex, 
      stopId: currentStop,
      stopOverallIndex
    });
    
    if (stops[stopOverallIndex]) {
      const stopLat = stops[stopOverallIndex].lat;
      const stopLng = stops[stopOverallIndex].lng;
      
      console.log("Updating game current point", { stopLat, stopLng, gameId: game.id });
      
      // Update game's current_point in Supabase
      const { error } = await supabase
        .from("games")
        .update({ current_point: { lat: stopLat, lng: stopLng } })
        .eq("id", game.id);
      
      if (error) {
        console.error("Error updating game current point:", error);
      }
      
      // Add a step to record this disembarkation
      const { error: stepError } = await supabase
        .from("game_steps")
        .insert({
          game_id: game.id,
          start_lat: stopLat,
          start_lng: stopLng,
          end_lat: stopLat,
          end_lng: stopLng,
          step_type: 99 // Special code for getting off
        });
        
      if (stepError) {
        console.error("Error inserting get-off step:", stepError);
      }
      
      // First close the modal
      setShowBoardOptions(false);
      setIsBoarded(false);
      onClose();
      
      // Then navigate to the stop location
      if (onNavigate) {
        onNavigate(stopLat, stopLng);
      }
    } else {
      console.log("Could not find stop for getting off");
      setShowBoardOptions(false);
      setIsBoarded(false);
      onClose();
    }
  };

  const handleNextStation = async () => {
    console.log("handleNextStation called - Initial state:", { 
      currentStopIndex, 
      firstStopIndex,
      selectedDirection,
      isAnimating,
      activelyViewedStopId
    });
    
    // Get the current direction's ordered stops
    const currentDirection = directions?.find(d => d.direction_id === selectedDirection);
    if (!currentDirection) {
      console.error("No current direction found. Available directions:", directions);
      return;
    }
    console.log("Current direction found:", { 
      directionId: currentDirection.direction_id, 
      stopIdsCount: currentDirection.stop_ids.length 
    });

    // Get ordered stops for the current direction
    const orderedStops = currentDirection.stop_ids
      .map(stopId => {
        const stop = stops.find(stop => stop.stop_id === stopId);
        if (!stop) console.warn(`Stop with ID ${stopId} not found in stops array`);
        return stop;
      })
      .filter((stop): stop is Stop => stop !== undefined);
    
    console.log("Ordered stops processing:", {
      originalStopIdsCount: currentDirection.stop_ids.length,
      filteredStopsCount: orderedStops.length,
      firstFewStops: orderedStops.slice(0, 3).map(s => ({ id: s.stop_id, name: s.stop_name })),
      lastFewStops: orderedStops.slice(-3).map(s => ({ id: s.stop_id, name: s.stop_name }))
    });
    
    if (currentStopIndex >= orderedStops.length) {
      console.error("Current stop index out of bounds:", {
        currentStopIndex,
        orderedStopsLength: orderedStops.length
      });
      return;
    }

    // Check if we can move to the next station
    if (currentStopIndex < orderedStops.length - 1 && !isAnimating) {
      console.log("Moving to next station", { 
        currentStopIndex, 
        orderedStopsLength: orderedStops.length,
        currentStopName: orderedStops[currentStopIndex]?.stop_name,
        isAnimating 
      });
      
      // Find the index of the next stop in the ordered list
      const nextStopIndex = currentStopIndex + 1;
      if (nextStopIndex >= orderedStops.length) {
        console.error("Next stop index out of bounds:", {
          nextStopIndex,
          orderedStopsLength: orderedStops.length
        });
        return;
      }
      
      console.log("Next stop calculation:", {
        nextStopIndex,
        nextStopId: orderedStops[nextStopIndex]?.stop_id,
        nextStopName: orderedStops[nextStopIndex]?.stop_name
      });

      // Get current and next stop coordinates for animation
      const currentStopCoords: [number, number] = [orderedStops[currentStopIndex].lng, orderedStops[currentStopIndex].lat];
      const nextStopCoords: [number, number] = [orderedStops[nextStopIndex].lng, orderedStops[nextStopIndex].lat];

      console.log("Animation coordinates:", {
        from: {
          coords: currentStopCoords,
          name: orderedStops[currentStopIndex].stop_name
        },
        to: {
          coords: nextStopCoords,
          name: orderedStops[nextStopIndex].stop_name
        }
      });

      // Start the animation
      setIsAnimating(true);
      console.log("Starting line animation. isAnimating set to:", true);
      animateLine(currentStopCoords, nextStopCoords);

      // After animation completes, update the stops and UI
      setTimeout(async () => {
        console.log("Animation timeout triggered. About to update next stop. Previous currentStopIndex:", currentStopIndex);
        
        // Update current stop index
        setCurrentStopIndex(prev => {
          console.log("Updating currentStopIndex from", prev, "to", prev + 1);
          return prev + 1;
        });
        
        console.log("After setCurrentStopIndex call, current value is still:", currentStopIndex, 
          "(Note: React state updates are asynchronous, so this value won't reflect the change yet)");
        
        if (mapRef.current && mapRef.current.getSource('stops')) {
          console.log("Updating map sources after animation");
          // Clean up animated line after we're ready to show the updated stop
          try {
            if (mapRef.current.getLayer('animated-line-layer')) {
              console.log("Removing animated-line-layer");
              mapRef.current.removeLayer('animated-line-layer');
            }
            if (mapRef.current.getSource('animated-line')) {
              console.log("Removing animated-line source");
              mapRef.current.removeSource('animated-line');
            }
          } catch (error) {
            console.error("Error cleaning up animation layers:", error);
          }

          // Get the stops from boarding stop to next stop
          let updatedStops = orderedStops.slice(firstStopIndex, nextStopIndex + 1);
          
          console.log("Updated stops after moving:", {
            count: updatedStops.length,
            firstStopIndex,
            nextStopIndex,
            firstStop: updatedStops[0]?.stop_name,
            lastStop: updatedStops[updatedStops.length - 1]?.stop_name,
            allStopNames: updatedStops.map(s => s.stop_name)
          });
          
          // Update current_stop property for all stops
          updatedStops = updatedStops.map((stop, idx) => {
            const isCurrent = idx === updatedStops.length - 1;
            if (isCurrent) {
              console.log(`Marking stop "${stop.stop_name}" as current`);
            }
            return {
              ...stop,
              current_stop: isCurrent // last stop is current
            };
          });

          // Update chevron marker and center map
          const currentStop = updatedStops.find(stop => stop.current_stop);
          if (currentStop) {
            console.log("Setting activelyViewedStopId to:", currentStop.stop_id);
            setActivelyViewedStopId(currentStop.stop_id);
            const nextStop = orderedStops[nextStopIndex + 1];
            console.log("Updating chevron marker from", currentStop.stop_name, "to", nextStop?.stop_name || "NONE (end of line)");
            updateChevronMarker(currentStop, nextStop);
            
            // Center map on current stop
            console.log("Centering map on current stop:", [currentStop.lng, currentStop.lat]);
            mapRef.current.setCenter([currentStop.lng, currentStop.lat]);
          } else {
            console.error("No current stop found after update");
          }

          // Update stops data source
          console.log("Updating map with new stops after moving:", updatedStops.length);
          try {
            (mapRef.current.getSource('stops') as mapboxgl.GeoJSONSource).setData({
              type: 'FeatureCollection',
              features: updatedStops.map(stop => ({
                type: 'Feature',
                geometry: {
                  type: 'Point',
                  coordinates: [stop.lng, stop.lat]
                },
                properties: {
                  stop_id: stop.stop_id,
                  stop_name: stop.stop_name,
                  routes: stop.routes,
                  is_first_stop: stop.current_stop || stops.find(s => s.current_stop)?.stop_name === stop.stop_name
                }
              }))
            });
          } catch (error) {
            console.error("Error updating stops data source:", error);
          }

          // Update route line
          const coordinates = updatedStops.map(stop => [stop.lng, stop.lat]);
          console.log("Updating route line with coordinates:", coordinates.length);
          try {
            (mapRef.current.getSource('route-line') as mapboxgl.GeoJSONSource).setData({
              type: 'Feature',
              properties: {},
              geometry: {
                type: 'LineString',
                coordinates: coordinates
              }
            });
          } catch (error) {
            console.error("Error updating route line:", error);
          }

          // Insert step in game_steps table
          const sourceStop = orderedStops[currentStopIndex];
          const destinationStop = orderedStops[nextStopIndex];
          console.log("Recording step in game:", { 
            sourceStopId: sourceStop.stop_id,
            sourceStop: sourceStop.stop_name, 
            destinationStopId: destinationStop.stop_id,
            destinationStop: destinationStop.stop_name,
            gameId: game.id
          });
          
          // Convert route type to number (3 for bus, 1 for subway, etc.)
          const routeType = sourceStop.routes?.find(r => r.route_short_name === routeName)?.type || '3';
          const routeTypeNumber = routeType === 'bus' ? 3 : 
                                routeType === 'subway' ? 1 : 
                                routeType === 'tram' ? 0 : 
                                routeType === 'ferry' ? 4 : 3; // Default to bus (3) if unknown
          
          console.log("Route type information:", { routeName, routeType, routeTypeNumber });
          
          // Insert step in game_steps table
          try {
            const { data, error: stepError } = await supabase
              .from("game_steps")
              .insert({
                game_id: game.id,
                start_lat: sourceStop.lat,
                start_lng: sourceStop.lng,
                end_lat: destinationStop.lat,
                end_lng: destinationStop.lng,
                step_type: routeType
              })
              .select();

            if (stepError) {
              console.error("Error inserting step:", stepError);
            } else {
              console.log("Successfully inserted game step:", data);
            }
          } catch (error) {
            console.error("Exception during game step insertion:", error);
          }
          
          // Only now set isAnimating to false, after all UI updates and database operations are complete
          console.log("Setting isAnimating to false");
          setIsAnimating(false);
        } else {
          console.error("Map reference or stops source not available");
          setIsAnimating(false);
        }
      }, 3000); // Wait for animation to complete
    } else {
      console.log("Cannot move to next station", { 
        currentStopIndex, 
        orderedStopsLength: orderedStops.length, 
        isAnimating,
        condition1: currentStopIndex < orderedStops.length - 1,
        condition2: !isAnimating
      });
    }
  };

  // Add function to handle direction change when reaching end of line
  const handleEndOfLineDirectionChange = () => {
    const nextDirection = getNextAvailableDirection();
    console.log("Handling end of line direction change", { 
      nextDirection: nextDirection?.direction_id 
    });

    if (nextDirection) {
      // Clean up animated line after we're ready to show the updated direction
      if (mapRef.current?.getLayer('animated-line-layer')) {
        mapRef.current.removeLayer('animated-line-layer');
      }
      if (mapRef.current?.getSource('animated-line')) {
        mapRef.current.removeSource('animated-line');
      }
      
      // Get ordered stops for the next direction
      const exCurrentStop = stops.findIndex(stop => stop.current_stop);
      stops[exCurrentStop].current_stop = false;
      const newCurrentStopId = nextDirection.stop_ids[0];
      const newCurrentStopIndexInStops = stops.findIndex(stop => stop.stop_id === newCurrentStopId);
      stops[newCurrentStopIndexInStops].current_stop = true;
      const orderedStops = nextDirection.stop_ids
        .map(stopId => stops.find(stop => stop.stop_id === stopId))
        .filter((stop): stop is Stop => stop !== undefined);

      console.log("New direction ordered stops:", {
        count: orderedStops.length,
        firstStop: orderedStops[0]?.stop_name
      });

      // Find the index of current stop in the new direction
      const currentStop = orderedStops[0];
      const newCurrentStopIndex = 0;
      
      // Update state variables
      setFirstStopIndex(newCurrentStopIndex);
      setCurrentStopIndex(newCurrentStopIndex);
      setSelectedDirection(nextDirection.direction_id);

      // Update the map
      if (mapRef.current && mapRef.current.getSource('stops')) {
        // When in boarding mode, only show from boarding to current (just one stop when changing direction)
        // Otherwise show just the current stop
        let filteredStops = isBoarded 
          ? [orderedStops[newCurrentStopIndex]]
          : [orderedStops[newCurrentStopIndex]];
        
        console.log("Filtered stops for new direction:", {
          count: filteredStops.length,
          isBoarded,
          stops: filteredStops.map(s => s.stop_name)
        });
        
        let updatedStops = filteredStops.map((stop, index) => ({
          ...stop,
          current_stop: index === 0  // First stop in filtered stops is current
        }));

        // Update chevron marker
        const nextStop = orderedStops[newCurrentStopIndex + 1];
        if (currentStop) {
          updateChevronMarker(currentStop, nextStop);
        }

        // Update stops data source
        console.log("Updating map with new direction stops:", updatedStops.length);
        (mapRef.current.getSource('stops') as mapboxgl.GeoJSONSource).setData({
          type: 'FeatureCollection',
          features: updatedStops.map(stop => ({
            type: 'Feature',
            geometry: {
              type: 'Point',
              coordinates: [stop.lng, stop.lat]
            },
            properties: {
              stop_id: stop.stop_id,
              stop_name: stop.stop_name,
              routes: stop.routes,
              is_first_stop: stop.current_stop || stops.find(s => s.current_stop)?.stop_name === stop.stop_name
            }
          }))
        });

        // Update route line
        const coordinates = updatedStops.map(stop => [stop.lng, stop.lat]);
        console.log("Updating route line for new direction with coordinates:", coordinates.length);
        (mapRef.current.getSource('route-line') as mapboxgl.GeoJSONSource).setData({
          type: 'Feature',
          properties: {},
          geometry: {
            type: 'LineString',
            coordinates: coordinates
          }
        });

        // Center map on current stop
        if (currentStop) {
          mapRef.current.setCenter([currentStop.lng, currentStop.lat]);
        }
        
        // Now set isAnimating to false after all updates are complete
        setIsAnimating(false);
        console.log("End of line direction change complete");
      }
    } else {
      console.log("No next direction available at end of line");
    }
  };

  // Check if we're at end of line on first load
  useEffect(() => {
    if (selectedDirection !== undefined && directions) {
      const currentDirection = directions.find(d => d.direction_id === selectedDirection);
      const isEndOfLine = currentDirection && isCurrentStopLastInDirection(currentDirection);
      console.log("Checking if at end of line on load", { isEndOfLine });
      if (isEndOfLine) {
        handleEndOfLineDirectionChange();
      }
    }
  }, [selectedDirection, directions]);

  if (!isOpen) return null;

  let connectedRoutesToDisplay: RouteInfo[] = [];
  if (showBoardOptions) {
    const currentStopForBoarding = stops.find(s => s.stop_id === activelyViewedStopId);
    if (currentStopForBoarding && currentStopForBoarding.routes) {
      const rawConnectedRoutes = currentStopForBoarding.routes.filter(
        r => r.route_short_name &&
             r.route_short_name !== routeName && // Filter out the main route of the modal
             r.route_short_name[0] !== 'N'       // Filter out 'N' routes as per page.tsx
      );

      const letterRoutes: RouteInfo[] = [];
      const numberRoutes: RouteInfo[] = [];

      rawConnectedRoutes.forEach(r => {
        if (r.route_short_name && r.route_short_name[0] === 'M' && r.route_short_name !== routeName) { // Specific check from page.tsx
           letterRoutes.push(r);
        } else {
           numberRoutes.push(r); // All others go to numberRoutes as per page.tsx logic
        }
      });

      numberRoutes.sort((a, b) => Number(a.route_short_name) - Number(b.route_short_name));
      letterRoutes.sort((a, b) => a.route_short_name.localeCompare(b.route_short_name));
      
      connectedRoutesToDisplay = [...letterRoutes, ...numberRoutes];
    }
  }

  return (
    <div
      style={{
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        backgroundColor: 'rgba(0, 0, 0, 0.5)',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        zIndex: 1000,
      }}
      onClick={onClose}
    >
      <div
        style={{
          backgroundColor: 'white',
          padding: '20px',
          borderRadius: '8px',
          width: '80%',
          height: '80%',
          maxWidth: '1000px',
          maxHeight: '800px',
          position: 'relative',
        }}
        onClick={e => e.stopPropagation()}
      >
        <div style={{ marginBottom: '10px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <h2 style={{ margin: 0, fontSize: '1.5rem' }}>Stops for Route: {routeName}</h2>
          {directions && directions.length > 0 && !isBoarded && (
            <div style={{ display: 'flex', gap: '10px', alignItems: 'center' }}>
              <div style={{ 
                display: 'flex', 
                alignItems: 'center', 
                gap: '12px',
                backgroundColor: '#f5f5f5',
                padding: '4px',
                borderRadius: '20px',
                boxShadow: 'inset 0 2px 4px rgba(0,0,0,0.1)'
              }}>
                {directions.map((dir) => {
                  const lastStopId = dir.stop_ids[dir.stop_ids.length - 1];
                  const lastStop = stops.find(s => s.stop_id === lastStopId);
                  const isSelected = dir.direction_id === selectedDirection;
                  const isAvailable = hasCurrentStop(dir);
                  
                  return (
                    <div
                      key={dir.direction_id}
                      onClick={() => isAvailable && handleDirectionChange(dir.direction_id)}
                      style={{
                        padding: '8px 16px',
                        borderRadius: '16px',
                        cursor: isAvailable ? 'pointer' : 'not-allowed',
                        backgroundColor: isSelected ? '#007bff' : 'transparent',
                        color: isAvailable ? (isSelected ? 'white' : '#666') : '#999',
                        transition: 'all 0.2s ease',
                        whiteSpace: 'nowrap',
                        fontSize: '14px',
                        fontWeight: isSelected ? '500' : '400',
                        opacity: isAvailable ? 1 : 0.5,
                      }}
                    >
                      To: {lastStop?.stop_name || ''}
                    </div>
                  );
                })}
              </div>
            </div>
          )}
        </div>
        <div
          ref={mapContainer}
          style={{
            width: '100%',
            height: 'calc(100% - 40px)',
            borderRadius: '4px',
            overflow: 'hidden',
          }}
        />
        <div style={{
          position: 'absolute',
          bottom: '20px',
          left: '50%',
          transform: 'translateX(-50%)',
          zIndex: 1000,
        }}>
          {!showBoardOptions ? (
            <button
              onClick={handleBoardBus}
              style={{
                backgroundColor: '#007bff',
                color: 'white',
                border: 'none',
                padding: '12px 24px',
                borderRadius: '8px',
                fontSize: '16px',
                fontWeight: '600',
                cursor: 'pointer',
                boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
                transition: 'all 0.2s ease',
              }}
              onMouseOver={(e) => e.currentTarget.style.backgroundColor = '#0056b3'}
              onMouseOut={(e) => e.currentTarget.style.backgroundColor = '#007bff'}
            >
              Board Bus
            </button>
          ) : (
            <>
              {/* Action Buttons Container */}
              <div style={{
                backgroundColor: 'white',
                padding: '10px',
                borderRadius: '8px',
                boxShadow: '0 2px 8px rgba(0, 0, 0, 0.2)',
                marginBottom: '10px',
              }}>
                <div style={{
                  display: 'flex',
                  gap: '10px',
                  justifyContent: 'center',
                  alignItems: 'center',
                }}>
                  <button
                    onClick={handleGetOff}
                    disabled={isAnimating}
                    style={{
                      backgroundColor: isAnimating ? '#6c757d' : '#dc3545',
                      color: 'white',
                      border: 'none',
                      padding: '10px 20px',
                      borderRadius: '6px',
                      fontSize: '14px',
                      height: '40px',
                      fontWeight: '600',
                      cursor: isAnimating ? 'not-allowed' : 'pointer',
                      transition: 'all 0.2s ease',
                      opacity: isAnimating ? 0.65 : 1,
                    }}
                    onMouseOver={(e) => {
                      if (!isAnimating) {
                        e.currentTarget.style.backgroundColor = '#c82333';
                      }
                    }}
                    onMouseOut={(e) => {
                      if (!isAnimating) {
                        e.currentTarget.style.backgroundColor = '#dc3545';
                      }
                    }}
                  >
                    Get Off
                  </button>
                  {(() => {
                    const currentDirection = directions?.find(d => d.direction_id === selectedDirection);
                    const isEndOfLine = currentDirection && isCurrentStopLastInDirection(currentDirection);
                    const nextDirection = getNextAvailableDirection();

                    // Get ordered stops for the current direction
                    const orderedStops = currentDirection?.stop_ids
                      .map(stopId => stops.find(stop => stop.stop_id === stopId))
                      .filter((stop): stop is Stop => stop !== undefined) || [];

                    if (isEndOfLine && !nextDirection) {
                      return (
                        <button
                          disabled
                          style={{
                            backgroundColor: '#6c757d',
                            color: 'white',
                            border: 'none',
                            padding: '10px 20px',
                            borderRadius: '6px',
                            fontSize: '14px',
                            height: '40px',
                            fontWeight: '600',
                            cursor: 'not-allowed',
                            opacity: 0.65,
                          }}
                        >
                          End of Line
                        </button>
                      );
                    }

                    return (
                      <button
                        onClick={() => {
                          if (isEndOfLine && nextDirection) {
                            // Animate transition between directions
                            // Get the last stop of current direction
                            const currentLastStop = orderedStops[orderedStops.length - 1];
                            // Get the first stop of next direction
                            const nextFirstStop = stops.find(stop => stop.stop_id === nextDirection.stop_ids[0]);
                            
                            if (currentLastStop && nextFirstStop) {
                              // Set animating state to prevent further clicks
                              setIsAnimating(true); // Will remain true until handleEndOfLineDirectionChange completes
                              // Animate between the last stop of current direction and first stop of next
                              animateLine(
                                [currentLastStop.lng, currentLastStop.lat],
                                [nextFirstStop.lng, nextFirstStop.lat],
                                3000 // Slightly longer animation for direction change
                              );
                              
                              // After animation starts, queue up the direction change
                              setTimeout(() => {
                                handleEndOfLineDirectionChange();
                                // No need to set isAnimating(false) here as it's now done inside handleEndOfLineDirectionChange
                              }, 3000);
                            } else {
                              // Fallback if we couldn't find the stops
                              handleEndOfLineDirectionChange();
                            }
                          } else {
                            handleNextStation();
                            // No need to set isAnimating(false) here as it's now done inside handleNextStation
                          }
                        }}
                        disabled={isAnimating}
                        style={{
                          backgroundColor: isAnimating ? '#6c757d' : '#28a745',
                          color: 'white',
                          border: 'none',
                          padding: '10px 20px',
                          borderRadius: '6px',
                          fontSize: '14px',
                          height: '40px',
                          fontWeight: '600',
                          cursor: isAnimating ? 'not-allowed' : 'pointer',
                          transition: 'all 0.2s ease',
                          opacity: isAnimating ? 0.65 : 1,
                          minWidth: '180px',
                          whiteSpace: 'nowrap',
                        }}
                        onMouseOver={(e) => {
                          if (!isAnimating) {
                            e.currentTarget.style.backgroundColor = '#218838';
                          }
                        }}
                        onMouseOut={(e) => {
                          if (!isAnimating) {
                            e.currentTarget.style.backgroundColor = '#28a745';
                          }
                        }}
                      >
                        {isAnimating ? 'Traveling...' : (isEndOfLine ? 'Continue to Next Direction' : 'Go to Next Station')}
                      </button>
                    );
                  })()}
                </div>
              </div>

              {/* Connected Routes Container */}
              {connectedRoutesToDisplay.length > 0 && (
                <div style={{
                  display: 'flex',
                  justifyContent: 'center',
                  width: '100%',
                }}>
                  <div style={{
                    backgroundColor: 'rgba(0, 0, 0, 0.4)',
                    color: '#1a1a1a',
                    padding: '10px 15px',
                    borderRadius: '8px',
                    maxHeight: '30vh',
                    overflowY: 'auto',
                    boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
                    width: 'fit-content',
                    minWidth: '200px',
                  }}>
                    <div style={{ display: 'flex', flexWrap: 'wrap', gap: '5px 10px' }}>
                      {connectedRoutesToDisplay.map((route, index) => (
                        <span
                          key={index}
                          style={{
                            backgroundColor: 'rgba(255, 255, 255, 0.9)',
                            padding: '5px 10px',
                            borderRadius: '4px',
                            fontSize: '1.1rem',
                            fontWeight: '600',
                            cursor: 'pointer',
                            display: 'flex',
                            alignItems: 'center',
                            gap: '5px',
                            color: '#1a1a1a',
                            transition: 'background-color 0.2s ease'
                          }}
                        >
                          {route.type && (
                            <img
                              src={`/${route.type}.png`}
                              alt={`${route.type} icon`}
                              style={{ width: '20px', height: '20px', objectFit: 'contain' }}
                            />
                          )}
                          {route.route_short_name}
                        </span>
                      ))}
                    </div>
                  </div>
                </div>
              )}
            </>
          )}
        </div>
      </div>
    </div>
  );
};

export default StopsMapModal; 