'use client'

import { useEffect, useState, useCallback } from 'react'
import { GoogleMap, MarkerF, PolylineF } from '@react-google-maps/api'
import { Delivery, Driver } from '@/lib/types'

interface Props {
  driver: Driver
  deliveries: Delivery[]
  currentTarget: Delivery | null
  routeHistory: { lat: number; lng: number }[]
}

const containerStyle = {
  width: '100%',
  height: '100%',
}

// Custom marker icons for Google Maps
// Use plain objects instead of google.maps.Size/Point to avoid "not a constructor" errors
const createDeliveryIcon = (color: string): google.maps.Icon => ({
  url: `data:image/svg+xml,${encodeURIComponent(
    `<svg xmlns="http://www.w3.org/2000/svg" width="25" height="41" viewBox="0 0 25 41">
      <path fill="${color}" d="M12.5 0C5.6 0 0 5.6 0 12.5c0 9.4 12.5 28.5 12.5 28.5s12.5-19.1 12.5-28.5C25 5.6 19.4 0 12.5 0z"/>
      <circle fill="white" cx="12.5" cy="12.5" r="5"/>
    </svg>`
  )}`,
  scaledSize: { width: 25, height: 41 } as any,
  anchor: { x: 12, y: 41 } as any,
})

const driverIcon: google.maps.Icon = {
  url: `data:image/svg+xml,${encodeURIComponent(
    `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
      <circle cx="16" cy="16" r="14" fill="%233b82f6" stroke="white" stroke-width="2"/>
      <text x="16" y="22" text-anchor="middle" font-size="16">🚗</text>
    </svg>`
  )}`,
  scaledSize: { width: 32, height: 32 } as any,
  anchor: { x: 16, y: 16 } as any,
}

// Decode Google polyline string to array of coordinates
function decodePolyline(encoded: string): google.maps.LatLngLiteral[] {
  const points: google.maps.LatLngLiteral[] = []
  let index = 0
  let lat = 0
  let lng = 0
  
  while (index < encoded.length) {
    let b
    let shift = 0
    let result = 0
    
    do {
      b = encoded.charCodeAt(index++) - 63
      result |= (b & 0x1f) << shift
      shift += 5
    } while (b >= 0x20)
    
    const dlat = (result & 1) ? ~(result >> 1) : (result >> 1)
    lat += dlat
    
    shift = 0
    result = 0
    
    do {
      b = encoded.charCodeAt(index++) - 63
      result |= (b & 0x1f) << shift
      shift += 5
    } while (b >= 0x20)
    
    const dlng = (result & 1) ? ~(result >> 1) : (result >> 1)
    lng += dlng
    
    points.push({ lat: lat / 1e5, lng: lng / 1e5 })
  }
  
  return points
}

// Fetch route from Google Directions API via our proxy endpoint
async function fetchGoogleRoute(
  origin: google.maps.LatLngLiteral,
  destination: google.maps.LatLngLiteral,
  waypoints?: google.maps.LatLngLiteral[]
): Promise<google.maps.LatLngLiteral[]> {
  const originStr = `${origin.lat},${origin.lng}`
  const destinationStr = `${destination.lat},${destination.lng}`
  const waypointsStr = waypoints
    ? waypoints.map(wp => `${wp.lat},${wp.lng}`).join('|')
    : ''

  let url = `/api/directions?origin=${encodeURIComponent(originStr)}&destination=${encodeURIComponent(destinationStr)}`
  if (waypointsStr) {
    url += `&waypoints=${encodeURIComponent(waypointsStr)}`
  }

  try {
    const response = await fetch(url)
    const data = await response.json()

    if (data.routes && data.routes.length > 0) {
      // Decode the overview_polyline string
      const encoded = data.routes[0].overview_polyline?.points
      if (encoded) {
        return decodePolyline(encoded)
      }
    }
  } catch (error) {
    console.error('Google Directions API error:', error)
  }

  return []
}

export default function DeliveryMapInner({ driver, deliveries, currentTarget, routeHistory }: Props) {
  const [routePath, setRoutePath] = useState<google.maps.LatLngLiteral[]>([])
  const [targetRoutePath, setTargetRoutePath] = useState<google.maps.LatLngLiteral[]>([])
  const [loadingRoute, setLoadingRoute] = useState(false)
  const [map, setMap] = useState<google.maps.Map | null>(null)

  // Fetch route history (completed route)
  useEffect(() => {
    if (routeHistory.length < 2) {
      setRoutePath([])
      return
    }

    setLoadingRoute(true)
    const origin = { lat: routeHistory[0].lat, lng: routeHistory[0].lng }
    const destination = { lat: routeHistory[routeHistory.length - 1].lat, lng: routeHistory[routeHistory.length - 1].lng }
    const waypoints = routeHistory.slice(1, -1)

    fetchGoogleRoute(origin, destination, waypoints).then(path => {
      setRoutePath(path)
      setLoadingRoute(false)
    })
  }, [routeHistory])

  // Fetch route to current target
  useEffect(() => {
    if (!currentTarget) {
      setTargetRoutePath([])
      return
    }

    setLoadingRoute(true)
    const origin = { lat: driver.lat, lng: driver.lng }
    const destination = { lat: currentTarget.lat, lng: currentTarget.lng }

    fetchGoogleRoute(origin, destination).then(path => {
      setTargetRoutePath(path)
      setLoadingRoute(false)
    })
  }, [currentTarget, driver])

  // Auto-fit map bounds when deliveries change
  useEffect(() => {
    if (!map) return

    const allPoints = [
      { lat: driver.lat, lng: driver.lng },
      ...deliveries.map(d => ({ lat: d.lat, lng: d.lng })),
    ]

    const bounds = new window.google.maps.LatLngBounds()
    allPoints.forEach(point => {
      bounds.extend(point)
    })

    map.fitBounds(bounds, { top: 50, right: 50, bottom: 50, left: 50 })
  }, [map, driver, deliveries])

  // Calculate map center
  const allPoints = [
    { lat: driver.lat, lng: driver.lng },
    ...deliveries.map(d => ({ lat: d.lat, lng: d.lng })),
  ]

  const centerLat = allPoints.reduce((sum, p) => sum + p.lat, 0) / allPoints.length
  const centerLng = allPoints.reduce((sum, p) => sum + p.lng, 0) / allPoints.length

  const onLoad = useCallback((map: google.maps.Map) => {
    setMap(map as any)
  }, [])

  return (
    <div className="bg-gray-900 rounded-xl border border-gray-700 overflow-hidden relative h-[300px] sm:h-[400px] lg:h-[500px]">
      <GoogleMap
        mapContainerStyle={containerStyle}
        center={{ lat: centerLat, lng: centerLng }}
        zoom={12}
        options={{
          scrollwheel: true,
          styles: [
            { elementType: "geometry", stylers: [{ color: "#242f3e" }] },
            { elementType: "labels.text.stroke", stylers: [{ color: "#242f3e" }] },
            { elementType: "labels.text.fill", stylers: [{ color: "#746855" }] },
            {
              featureType: "administrative.locality",
              elementType: "labels.text.fill",
              stylers: [{ color: "#d59563" }],
            },
            {
              featureType: "poi",
              elementType: "labels.text.fill",
              stylers: [{ color: "#d59563" }],
            },
            {
              featureType: "poi.park",
              elementType: "geometry",
              stylers: [{ color: "#263c3f" }],
            },
            {
              featureType: "poi.park",
              elementType: "labels.text.fill",
              stylers: [{ color: "#6b9a76" }],
            },
            {
              featureType: "road",
              elementType: "geometry",
              stylers: [{ color: "#38414e" }],
            },
            {
              featureType: "road",
              elementType: "geometry.stroke",
              stylers: [{ color: "#212a37" }],
            },
            {
              featureType: "road",
              elementType: "labels.text.fill",
              stylers: [{ color: "#9ca5b3" }],
            },
            {
              featureType: "road.highway",
              elementType: "geometry",
              stylers: [{ color: "#746855" }],
            },
            {
              featureType: "road.highway",
              elementType: "geometry.stroke",
              stylers: [{ color: "#1f2835" }],
            },
            {
              featureType: "transit",
              elementType: "geometry",
              stylers: [{ color: "#2f3948" }],
            },
            {
              featureType: "transit.station",
              elementType: "labels.text.fill",
              stylers: [{ color: "#d59563" }],
            },
            {
              featureType: "water",
              elementType: "geometry",
              stylers: [{ color: "#17263c" }],
            },
            {
              featureType: "water",
              elementType: "labels.text.fill",
              stylers: [{ color: "#515c6d" }],
            },
          ],
        }}
        onLoad={onLoad}
      >
        {/* Route history - mengikuti jalan raya */}
        {routePath.length > 0 && (
          <PolylineF
            path={routePath}
            options={{ strokeColor: '#22c55e', strokeWeight: 4, strokeOpacity: 0.8 }}
          />
        )}

        {/* Route to current target - mengikuti jalan raya */}
        {targetRoutePath.length > 0 && (
          <PolylineF
            path={targetRoutePath}
            options={{ strokeColor: '#facc15', strokeWeight: 5, strokeOpacity: 0.9 }}
          />
        )}

        {/* Delivery markers */}
        {deliveries.map((d) => {
          const isTarget = currentTarget?.id === d.id
          const isCompleted = d.status === 'completed'
          const color = isCompleted ? '#16a34a' : isTarget ? '#facc15' : '#ef4444'

          return (
            <MarkerF
              key={d.id}
              position={{ lat: d.lat, lng: d.lng }}
              icon={createDeliveryIcon(color)}
              title={d.recipient}
            >
              {/* InfoWindow would go here if needed */}
            </MarkerF>
          )
        })}

        {/* Driver marker */}
        <MarkerF
          position={{ lat: driver.lat, lng: driver.lng }}
          icon={driverIcon}
          title={driver.name}
        />
      </GoogleMap>

      {/* Legend */}
      <div className="px-3 py-2 sm:px-4 sm:py-3 bg-gray-900 flex items-center gap-2 sm:gap-4 text-[10px] sm:text-xs text-gray-400 flex-wrap">
        <div className="flex items-center gap-1.5">
          <span className="w-2 sm:w-2.5 h-2 sm:h-2.5 rounded-full bg-red-500 inline-block" />
          Belum diantar
        </div>
        <div className="flex items-center gap-1.5">
          <span className="w-2 sm:w-2.5 h-2 sm:h-2.5 rounded-full bg-yellow-400 inline-block" />
          Target berikutnya
        </div>
        <div className="flex items-center gap-1.5">
          <span className="w-2 sm:w-2.5 h-2 sm:h-2.5 rounded-full bg-green-500 inline-block" />
          Selesai
        </div>
        {loadingRoute && (
          <span className="text-[10px] sm:text-xs text-gray-500 ml-auto">Memuat jalur...</span>
        )}
      </div>
    </div>
  )
}
