'use client';

import { useEffect, useRef } from 'react';
import type { Map as MaplibreMap } from 'maplibre-gl';
import type { RouteSegment } from '@/types';

interface RouteOverlayProps {
  map: MaplibreMap | null;
  segments: RouteSegment[];
  isLoading?: boolean;
  error?: string;
  summary?: string;
  totalDistance?: number;
  estimatedTime?: number;
  destinationName?: string;
  onClose?: () => void;
}

// Format distance in meters to a human-readable string
function formatDistance(meters: number): string {
  if (meters < 1000) {
    return `${Math.round(meters)}m`;
  }
  return `${(meters / 1000).toFixed(1)}km`;
}

// Format time in seconds to a human-readable string
function formatTime(seconds: number): string {
  if (seconds < 60) {
    return `${Math.round(seconds)}s`;
  }
  const mins = Math.floor(seconds / 60);
  if (mins < 60) {
    return `${mins} min`;
  }
  const hours = Math.floor(mins / 60);
  const remainingMins = mins % 60;
  return `${hours}h ${remainingMins}m`;
}

// Route line colors by segment type
const SEGMENT_COLORS = {
  outdoor: '#3b82f6', // blue
  indoor: '#8b5cf6',  // purple
  transition: '#f59e0b', // amber
};

export default function RouteOverlay({
  map,
  segments,
  isLoading,
  error,
  summary,
  totalDistance = 0,
  estimatedTime = 0,
  destinationName,
  onClose,
}: RouteOverlayProps) {
  const sourceAddedRef = useRef(false);

  // Add/update route layer on the map
  useEffect(() => {
    if (!map || segments.length === 0) {
      // Clean up existing route if no segments
      if (map && sourceAddedRef.current) {
        try {
          if (map.getLayer('route-line')) map.removeLayer('route-line');
          if (map.getLayer('route-line-outline')) map.removeLayer('route-line-outline');
          if (map.getSource('route')) map.removeSource('route');
          sourceAddedRef.current = false;
        } catch (e) {
          // Ignore cleanup errors
        }
      }
      return;
    }

    // Build GeoJSON features for all outdoor segments
    const outdoorSegments = segments.filter((s) => s.type === 'outdoor');
    const features = outdoorSegments.map((segment, index) => ({
      type: 'Feature' as const,
      properties: {
        segmentType: segment.type,
        index,
      },
      geometry: {
        type: 'LineString' as const,
        coordinates: segment.coordinates,
      },
    }));

    const geojson = {
      type: 'FeatureCollection' as const,
      features,
    };

    // Wait for map to be loaded
    const addRoute = () => {
      try {
        // Remove existing layers/source if they exist
        if (map.getLayer('route-line')) map.removeLayer('route-line');
        if (map.getLayer('route-line-outline')) map.removeLayer('route-line-outline');
        if (map.getSource('route')) map.removeSource('route');

        // Add source
        map.addSource('route', {
          type: 'geojson',
          data: geojson,
        });

        // Add outline layer (for better visibility)
        map.addLayer({
          id: 'route-line-outline',
          type: 'line',
          source: 'route',
          layout: {
            'line-join': 'round',
            'line-cap': 'round',
          },
          paint: {
            'line-color': '#1e3a5f',
            'line-width': 8,
            'line-opacity': 0.6,
          },
        });

        // Add main route line
        map.addLayer({
          id: 'route-line',
          type: 'line',
          source: 'route',
          layout: {
            'line-join': 'round',
            'line-cap': 'round',
          },
          paint: {
            'line-color': SEGMENT_COLORS.outdoor,
            'line-width': 5,
            'line-opacity': 0.9,
          },
        });

        sourceAddedRef.current = true;

        // Fit map to route bounds
        if (features.length > 0 && features[0].geometry.coordinates.length > 0) {
          const allCoords = features.flatMap((f) => f.geometry.coordinates);
          const bounds = allCoords.reduce(
            (acc, coord) => ({
              minLng: Math.min(acc.minLng, coord[0]),
              maxLng: Math.max(acc.maxLng, coord[0]),
              minLat: Math.min(acc.minLat, coord[1]),
              maxLat: Math.max(acc.maxLat, coord[1]),
            }),
            { minLng: Infinity, maxLng: -Infinity, minLat: Infinity, maxLat: -Infinity }
          );

          map.fitBounds(
            [
              [bounds.minLng, bounds.minLat],
              [bounds.maxLng, bounds.maxLat],
            ],
            { padding: 80, maxZoom: 16 }
          );
        }
      } catch (e) {
        console.error('Error adding route to map:', e);
      }
    };

    if (map.isStyleLoaded()) {
      addRoute();
    } else {
      map.once('load', addRoute);
    }

    // Cleanup on unmount
    return () => {
      if (map && sourceAddedRef.current) {
        try {
          if (map.getLayer('route-line')) map.removeLayer('route-line');
          if (map.getLayer('route-line-outline')) map.removeLayer('route-line-outline');
          if (map.getSource('route')) map.removeSource('route');
          sourceAddedRef.current = false;
        } catch (e) {
          // Ignore cleanup errors (map might be destroyed)
        }
      }
    };
  }, [map, segments]);

  // Don't render panel if no route data and not loading
  if (!isLoading && !error && segments.length === 0 && !destinationName) {
    return null;
  }

  return (
    <div className="absolute bottom-20 left-4 right-4 sm:left-auto sm:right-4 sm:w-80 z-40">
      <div className="bg-rmaps-dark/95 backdrop-blur-sm rounded-lg shadow-xl border border-white/10 overflow-hidden">
        {/* Header */}
        <div className="flex items-center justify-between px-4 py-3 border-b border-white/10">
          <div className="flex items-center gap-2">
            <svg className="w-5 h-5 text-rmaps-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" />
            </svg>
            <span className="font-medium text-white">Directions</span>
          </div>
          {onClose && (
            <button
              onClick={onClose}
              className="text-white/60 hover:text-white transition-colors p-1"
              aria-label="Close directions"
            >
              <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          )}
        </div>

        {/* Content */}
        <div className="p-4">
          {isLoading ? (
            <div className="flex items-center gap-3">
              <div className="w-5 h-5 border-2 border-rmaps-primary border-t-transparent rounded-full animate-spin" />
              <span className="text-white/80">Calculating route...</span>
            </div>
          ) : error ? (
            <div className="flex items-start gap-3">
              <svg className="w-5 h-5 text-red-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
              </svg>
              <div>
                <p className="text-red-400 text-sm">{error}</p>
              </div>
            </div>
          ) : (
            <>
              {/* Destination */}
              {destinationName && (
                <div className="mb-3">
                  <span className="text-white/60 text-xs">To</span>
                  <p className="text-white font-medium">{destinationName}</p>
                </div>
              )}

              {/* Stats */}
              <div className="flex items-center gap-6 mb-3">
                <div>
                  <span className="text-white/60 text-xs">Distance</span>
                  <p className="text-white font-medium text-lg">{formatDistance(totalDistance)}</p>
                </div>
                <div>
                  <span className="text-white/60 text-xs">Walking time</span>
                  <p className="text-white font-medium text-lg">{formatTime(estimatedTime)}</p>
                </div>
              </div>

              {/* Summary */}
              {summary && (
                <p className="text-white/70 text-sm">{summary}</p>
              )}

              {/* Segment breakdown for mixed routes */}
              {segments.some((s) => s.type === 'transition') && (
                <div className="mt-3 pt-3 border-t border-white/10">
                  <span className="text-white/60 text-xs">Route steps</span>
                  <div className="mt-2 space-y-2">
                    {segments.map((segment, index) => (
                      <div key={index} className="flex items-center gap-2 text-sm">
                        <div
                          className="w-3 h-3 rounded-full"
                          style={{ backgroundColor: SEGMENT_COLORS[segment.type] }}
                        />
                        <span className="text-white/80">
                          {segment.type === 'outdoor' && 'Walk outside'}
                          {segment.type === 'indoor' && `Level ${segment.level}`}
                          {segment.type === 'transition' && (segment.instructions || 'Change level')}
                        </span>
                        {segment.distance > 0 && (
                          <span className="text-white/50 ml-auto">
                            {formatDistance(segment.distance)}
                          </span>
                        )}
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </>
          )}
        </div>
      </div>
    </div>
  );
}
