"use client"

import { useState, useEffect, useRef } from "react"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { MapPin, Loader2, AlertCircle, Play, Route } from "lucide-react"

declare global {
  interface Window {
    L: any
  }
}

interface LocationData {
  latitude: number
  longitude: number
  accuracy: number
}

export function LocationMap() {
  const [location, setLocation] = useState<LocationData | null>(null)
  const [startLocation, setStartLocation] = useState<LocationData | null>(null)
  const [distance, setDistance] = useState<number | null>(null)
  const [isTracking, setIsTracking] = useState(false)
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [mapLoaded, setMapLoaded] = useState(false)
  const mapRef = useRef<HTMLDivElement>(null)
  const mapInstanceRef = useRef<any>(null)
  const startMarkerRef = useRef<any>(null)
  const currentMarkerRef = useRef<any>(null)
  const routeLineRef = useRef<any>(null)
  const watchIdRef = useRef<number | null>(null)

  const calculateDistance = (lat1: number, lon1: number, lat2: number, lon2: number): number => {
    const R = 6371 // Earth's radius in kilometers
    const dLat = ((lat2 - lat1) * Math.PI) / 180
    const dLon = ((lon2 - lon1) * Math.PI) / 180
    const a =
      Math.sin(dLat / 2) * Math.sin(dLat / 2) +
      Math.cos((lat1 * Math.PI) / 180) * Math.cos((lat2 * Math.PI) / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2)
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
    const calculatedDistance = R * c * 1000 // Convert to meters

    const MIN_DISTANCE_THRESHOLD = 5 // meters
    return calculatedDistance >= MIN_DISTANCE_THRESHOLD ? calculatedDistance : 0
  }

  useEffect(() => {
    const loadLeaflet = async () => {
      if (typeof window !== "undefined" && !window.L) {
        const link = document.createElement("link")
        link.rel = "stylesheet"
        link.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
        document.head.appendChild(link)

        const script = document.createElement("script")
        script.src = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
        script.onload = () => setMapLoaded(true)
        document.head.appendChild(script)
      } else if (window.L) {
        setMapLoaded(true)
      }
    }

    loadLeaflet()
  }, [])

  useEffect(() => {
    return () => {
      if (watchIdRef.current !== null) {
        navigator.geolocation.clearWatch(watchIdRef.current)
      }
    }
  }, [])

  useEffect(() => {
    if (mapLoaded && mapRef.current && (location || startLocation)) {
      const L = window.L

      if (!mapInstanceRef.current) {
        const initialLocation = startLocation || location
        const map = L.map(mapRef.current).setView([initialLocation!.latitude, initialLocation!.longitude], 15)

        L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
          attribution: "© OpenStreetMap contributors",
        }).addTo(map)

        mapInstanceRef.current = map
      }

      const map = mapInstanceRef.current

      if (startLocation && !startMarkerRef.current) {
        const startMarker = L.marker([startLocation.latitude, startLocation.longitude], {
          icon: L.divIcon({
            html: '<div style="background-color: #10b981; width: 24px; height: 24px; border-radius: 50%; border: 3px solid white; box-shadow: 0 2px 4px rgba(0,0,0,0.3);"><div style="color: white; font-size: 12px; font-weight: bold; text-align: center; line-height: 18px;">S</div></div>',
            className: "custom-div-icon",
            iconSize: [24, 24],
            iconAnchor: [12, 12],
          }),
        }).addTo(map)

        startMarker.bindPopup(`
          <div class="text-center">
            <strong>🚀 Start Location</strong><br/>
            Lat: ${startLocation.latitude.toFixed(6)}<br/>
            Lng: ${startLocation.longitude.toFixed(6)}
          </div>
        `)

        startMarkerRef.current = startMarker
      }

      if (location) {
        if (currentMarkerRef.current) {
          map.removeLayer(currentMarkerRef.current)
        }

        const currentMarker = L.marker([location.latitude, location.longitude], {
          icon: L.divIcon({
            html: '<div style="background-color: #3b82f6; width: 24px; height: 24px; border-radius: 50%; border: 3px solid white; box-shadow: 0 2px 4px rgba(0,0,0,0.3);"><div style="color: white; font-size: 12px; font-weight: bold; text-align: center; line-height: 18px;">📍</div></div>',
            className: "custom-div-icon",
            iconSize: [24, 24],
            iconAnchor: [12, 12],
          }),
        }).addTo(map)

        currentMarker.bindPopup(`
          <div class="text-center">
            <strong>📍 Current Location</strong><br/>
            Lat: ${location.latitude.toFixed(6)}<br/>
            Lng: ${location.longitude.toFixed(6)}<br/>
            Accuracy: ${location.accuracy.toFixed(0)}m
          </div>
        `)

        currentMarkerRef.current = currentMarker

        L.circle([location.latitude, location.longitude], {
          radius: location.accuracy,
          fillColor: "#3b82f6",
          fillOpacity: 0.15,
          color: "#3b82f6",
          weight: 2,
          dashArray: "5, 5",
        }).addTo(map)
      }

      if (startLocation && location) {
        if (routeLineRef.current) {
          map.removeLayer(routeLineRef.current)
        }

        const routeLine = L.polyline(
          [
            [startLocation.latitude, startLocation.longitude],
            [location.latitude, location.longitude],
          ],
          {
            color: "#ef4444",
            weight: 4,
            opacity: 0.8,
            dashArray: "10, 5",
          },
        ).addTo(map)

        routeLineRef.current = routeLine

        const group = L.featureGroup([startMarkerRef.current, currentMarkerRef.current])
        map.fitBounds(group.getBounds().pad(0.2))

        const dist = calculateDistance(
          startLocation.latitude,
          startLocation.longitude,
          location.latitude,
          location.longitude,
        )
        setDistance(dist)
      }
    }
  }, [location, startLocation, mapLoaded])

  const startTracking = () => {
    if (!navigator.geolocation) {
      setError("Geolocation is not supported by this browser.")
      return
    }

    setLoading(true)
    setError(null)
    setIsTracking(true)

    navigator.geolocation.getCurrentPosition(
      (position) => {
        const { latitude, longitude, accuracy } = position.coords
        setStartLocation({ latitude, longitude, accuracy })
        setLoading(false)

        watchIdRef.current = navigator.geolocation.watchPosition(
          (position) => {
            const { latitude, longitude, accuracy } = position.coords
            setLocation({ latitude, longitude, accuracy })
          },
          (error) => {
            let errorMessage = "Unable to retrieve your location."

            switch (error.code) {
              case error.PERMISSION_DENIED:
                errorMessage = "Location access denied. Please enable location permissions in your browser settings."
                break
              case error.POSITION_UNAVAILABLE:
                errorMessage = "Location information is unavailable. Please check your GPS/location services."
                break
              case error.TIMEOUT:
                errorMessage = "Location request timed out. Please try again or check your connection."
                break
            }

            setError(errorMessage)
          },
          {
            enableHighAccuracy: true,
            timeout: 30000, // Increased to 30 seconds
            maximumAge: 10000, // Allow cached location up to 10 seconds
          },
        )
      },
      (error) => {
        let errorMessage = "Unable to retrieve your location."

        switch (error.code) {
          case error.PERMISSION_DENIED:
            errorMessage = "Location access denied. Please enable location permissions in your browser settings."
            break
          case error.POSITION_UNAVAILABLE:
            errorMessage = "Location information is unavailable. Please check your GPS/location services."
            break
          case error.TIMEOUT:
            errorMessage = "Location request timed out. Please try again or check your connection."
            break
        }

        setError(errorMessage)
        setLoading(false)
        setIsTracking(false)
      },
      {
        enableHighAccuracy: true,
        timeout: 30000, // Increased to 30 seconds
        maximumAge: 30000, // Allow cached location up to 30 seconds for initial position
      },
    )
  }

  const resetTracking = () => {
    if (watchIdRef.current !== null) {
      navigator.geolocation.clearWatch(watchIdRef.current)
      watchIdRef.current = null
    }

    setStartLocation(null)
    setLocation(null)
    setDistance(null)
    setIsTracking(false)
    setError(null)

    if (mapInstanceRef.current) {
      mapInstanceRef.current.remove()
      mapInstanceRef.current = null
      startMarkerRef.current = null
      currentMarkerRef.current = null
      routeLineRef.current = null
    }
  }

  return (
    <div className="w-full mx-auto space-y-6">
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <MapPin className="h-5 w-5" />
            Location Distance Tracker
          </CardTitle>
          <CardDescription>Track distance between your start location and current position</CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="flex flex-wrap gap-2">
            {!isTracking ? (
              <Button onClick={startTracking} disabled={loading} className="flex-1 sm:flex-none">
                {loading ? (
                  <>
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    Starting...
                  </>
                ) : (
                  <>
                    <Play className="mr-2 h-4 w-4" />
                    Start Tracking
                  </>
                )}
              </Button>
            ) : (
              <Button onClick={resetTracking} variant="outline">
                Reset
              </Button>
            )}
          </div>

          {error && (
            <div className="flex items-center gap-2 p-3 bg-destructive/10 text-destructive rounded-md">
              <AlertCircle className="h-4 w-4" />
              <span className="text-sm">{error}</span>
            </div>
          )}

          {isTracking && distance !== null && (
            <div className="p-4 bg-green-50 border border-green-200 rounded-md">
              <div className="flex items-center gap-2 mb-2">
                <Route className="h-4 w-4 text-green-600" />
                <span className="font-medium text-green-800">Distance Traveled</span>
              </div>
              <div className="space-y-1">
                <div className="text-2xl font-bold text-green-900">{distance.toFixed(1)} meters</div>
                <div className="text-lg font-semibold text-green-700">{(distance / 1000).toFixed(3)} kilometers</div>
              </div>
            </div>
          )}

          {isTracking && (
            <div className="flex items-center gap-2 p-3 bg-blue-50 border border-blue-200 rounded-md">
              <div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse"></div>
              <span className="text-sm text-blue-700">Auto-updating location...</span>
            </div>
          )}

          {(startLocation || location) && (
            <div className="space-y-4">
              {startLocation && (
                <div className="p-4 bg-green-50 border border-green-200 rounded-md">
                  <div className="text-sm font-medium text-green-800 mb-2">Start Location</div>
                  <div className="grid grid-cols-2 gap-4">
                    <div className="text-center">
                      <div className="text-xs text-green-600">Latitude</div>
                      <div className="font-mono text-sm">{startLocation.latitude.toFixed(6)}</div>
                    </div>
                    <div className="text-center">
                      <div className="text-xs text-green-600">Longitude</div>
                      <div className="font-mono text-sm">{startLocation.longitude.toFixed(6)}</div>
                    </div>
                  </div>
                </div>
              )}

              {location && (
                <div className="p-4 bg-blue-50 border border-blue-200 rounded-md">
                  <div className="text-sm font-medium text-blue-800 mb-2">Current Location</div>
                  <div className="grid grid-cols-3 gap-4">
                    <div className="text-center">
                      <div className="text-xs text-blue-600">Latitude</div>
                      <div className="font-mono text-sm">{location.latitude.toFixed(6)}</div>
                    </div>
                    <div className="text-center">
                      <div className="text-xs text-blue-600">Longitude</div>
                      <div className="font-mono text-sm">{location.longitude.toFixed(6)}</div>
                    </div>
                    <div className="text-center">
                      <div className="text-xs text-blue-600">Accuracy</div>
                      <div className="font-mono text-sm">{location.accuracy.toFixed(0)}m</div>
                    </div>
                  </div>
                </div>
              )}
            </div>
          )}
        </CardContent>
      </Card>

      {(startLocation || location) && (
        <Card>
          <CardHeader>
            <CardTitle>Interactive Map</CardTitle>
            <CardDescription>
              {startLocation && location
                ? "Green marker shows start location, blue marker shows current location with route line"
                : startLocation
                  ? "Green marker shows your start location"
                  : "Blue marker shows your current location"}
            </CardDescription>
          </CardHeader>
          <CardContent>
            <div ref={mapRef} className="w-full h-96 rounded-md border bg-muted" style={{ minHeight: "400px" }} />
            {!mapLoaded && (startLocation || location) && (
              <div className="flex items-center justify-center h-96 bg-muted rounded-md">
                <div className="text-center">
                  <Loader2 className="h-8 w-8 animate-spin mx-auto mb-2" />
                  <p className="text-sm text-muted-foreground">Loading map...</p>
                </div>
              </div>
            )}
          </CardContent>
        </Card>
      )}
    </div>
  )
}
