import { useEffect, useRef, useState } from 'react'
import maplibregl from 'maplibre-gl'
import { useNMEA } from '../../hooks/useNMEA.js'
import { getApi } from '../../mock/index.js'
import 'maplibre-gl/dist/maplibre-gl.css'

export default function NavigationMap() {
  const { lat, lon, heading, sog } = useNMEA()
  const mapContainer = useRef(null)
  const map = useRef(null)
  const shipMarkerRef = useRef(null)
  const trackSourceRef = useRef(false)
  const [zoom, setZoom] = useState(11)

  const api = getApi()
  const snapshot = api.signalk.getSnapshot?.()
  const waypoints = api.signalk.getWaypoints?.() || []

  const mapLat = lat ?? 55.32
  const mapLon = lon ?? 15.22

  useEffect(() => {
    if (map.current) return

    map.current = new maplibregl.Map({
      container: mapContainer.current,
      style: {
        version: 8,
        sources: {
          'osm': {
            type: 'raster',
            tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
            tileSize: 256,
            attribution: '© OpenStreetMap contributors',
          },
          'seamark': {
            type: 'raster',
            tiles: ['https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png'],
            tileSize: 256,
            attribution: '© OpenSeaMap contributors',
          },
        },
        layers: [
          {
            id: 'osm-base',
            type: 'raster',
            source: 'osm',
            minzoom: 0,
            maxzoom: 19,
          },
          {
            id: 'seamark-overlay',
            type: 'raster',
            source: 'seamark',
            minzoom: 5,
            maxzoom: 19,
            paint: {
              'raster-opacity': 0.8,
            },
          },
        ],
        glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf',
      },
      center: [mapLon, mapLat],
      zoom: 11,
      pitch: 0,
      bearing: 0,
      antialias: true,
    })

    // Add navigation controls
    map.current.addControl(new maplibregl.NavigationControl(), 'top-right')

    // Add ship marker source and layer
    map.current.on('load', () => {
      if (!map.current.getSource('ship')) {
        map.current.addSource('ship', {
          type: 'geojson',
          data: {
            type: 'Feature',
            geometry: { type: 'Point', coordinates: [mapLon, mapLat] },
            properties: { heading: 0 },
          },
        })

        map.current.addLayer({
          id: 'ship-marker',
          type: 'symbol',
          source: 'ship',
          layout: {
            'icon-image': 'marker-blue',
            'icon-size': 1.2,
            'icon-rotate': ['get', 'heading'],
            'icon-allow-overlap': true,
            'icon-ignore-placement': true,
          },
        })
      }

      // Add track source for ship trail
      if (!map.current.getSource('track')) {
        map.current.addSource('track', {
          type: 'geojson',
          data: {
            type: 'Feature',
            geometry: { type: 'LineString', coordinates: [[mapLon, mapLat]] },
          },
        })

        map.current.addLayer({
          id: 'track-line',
          type: 'line',
          source: 'track',
          paint: {
            'line-color': '#0ea5e9',
            'line-width': 2,
            'line-opacity': 0.7,
            'line-dasharray': [5, 5],
          },
        })
        trackSourceRef.current = true
      }

      // Add waypoints
      if (waypoints.length > 0) {
        const waypointFeatures = waypoints.map((wp, idx) => ({
          type: 'Feature',
          geometry: { type: 'Point', coordinates: [wp.lon, wp.lat] },
          properties: { index: idx, isCurrent: idx === snapshot?.currentWaypoint },
        }))

        if (!map.current.getSource('waypoints')) {
          map.current.addSource('waypoints', {
            type: 'geojson',
            data: {
              type: 'FeatureCollection',
              features: waypointFeatures,
            },
          })

          map.current.addLayer({
            id: 'waypoint-circles',
            type: 'circle',
            source: 'waypoints',
            paint: {
              'circle-radius': 8,
              'circle-color': ['case', ['get', 'isCurrent'], '#0ea5e9', '#f59e0b'],
              'circle-stroke-width': 2,
              'circle-stroke-color': '#ffffff',
            },
          })

          map.current.addLayer({
            id: 'waypoint-labels',
            type: 'symbol',
            source: 'waypoints',
            layout: {
              'text-field': ['to-string', ['+', ['get', 'index'], 1]],
              'text-size': 12,
              'text-font': ['Open Sans Semibold'],
              'text-offset': [0, 0],
              'text-allow-overlap': true,
            },
            paint: {
              'text-color': '#ffffff',
              'text-halo-color': '#000000',
              'text-halo-width': 1,
            },
          })
        } else {
          map.current.getSource('waypoints').setData({
            type: 'FeatureCollection',
            features: waypointFeatures,
          })
        }
      }
    })

    map.current.on('zoom', () => setZoom(map.current.getZoom()))

    return () => {
      // Cleanup is handled by React
    }
  }, [])

  // Update ship position
  useEffect(() => {
    if (!map.current || lat == null || lon == null) return

    if (map.current.getSource('ship')) {
      const trackSource = map.current.getSource('track')
      if (trackSource && trackSourceRef.current) {
        const currentData = trackSource._data
        if (currentData.geometry.coordinates.length > 500) {
          currentData.geometry.coordinates.shift() // Keep last 500 points
        }
        currentData.geometry.coordinates.push([lon, lat])
        trackSource.setData(currentData)
      }

      map.current.getSource('ship').setData({
        type: 'Feature',
        geometry: { type: 'Point', coordinates: [lon, lat] },
        properties: { heading: heading ?? 0 },
      })

      // Auto-center on ship
      map.current.flyTo({
        center: [lon, lat],
        zoom: zoom,
        speed: 0.5,
        curve: 1,
      })
    }
  }, [lat, lon, heading, zoom])

  return (
    <div style={styles.container}>
      <div ref={mapContainer} style={styles.mapBox} />

      {/* Map Controls */}
      <div style={styles.controls}>
        <button
          className="icon ghost"
          onClick={() => map.current?.zoomIn()}
          title="Zoom in"
          style={{ fontSize: 18 }}
        >
          +
        </button>
        <button
          className="icon ghost"
          onClick={() => map.current?.zoomOut()}
          title="Zoom out"
          style={{ fontSize: 18 }}
        >
          −
        </button>
        <button
          className="icon ghost"
          onClick={() => {
            if (lat != null && lon != null) {
              map.current?.flyTo({
                center: [lon, lat],
                zoom: 12,
                duration: 1000,
              })
            }
          }}
          title="Center on ship"
          style={{ fontSize: 16 }}
        >
          ⊙
        </button>
      </div>

      {/* Info Panel */}
      {lat != null && lon != null && (
        <div style={styles.infoPanel}>
          <div style={styles.infoSection}>
            <div style={styles.infoRow}>
              <span style={styles.label}>Position</span>
              <span style={styles.value}>{lat.toFixed(5)}°</span>
            </div>
            <div style={styles.infoRow}>
              <span style={styles.label}></span>
              <span style={styles.value}>{lon.toFixed(5)}°</span>
            </div>
          </div>

          {heading != null && (
            <div style={styles.infoSection}>
              <div style={styles.infoRow}>
                <span style={styles.label}>Heading</span>
                <span style={styles.value}>{Math.round(heading)}°</span>
              </div>
            </div>
          )}

          {sog != null && (
            <div style={styles.infoSection}>
              <div style={styles.infoRow}>
                <span style={styles.label}>Speed</span>
                <span style={styles.value}>{(sog * 1.943844).toFixed(1)} kn</span>
              </div>
            </div>
          )}

          {waypoints.length > 0 && snapshot?.currentWaypoint != null && (
            <div style={styles.infoSection}>
              <div style={styles.infoRow}>
                <span style={styles.label}>Route</span>
                <span style={styles.value}>WP {snapshot.currentWaypoint + 1} / {waypoints.length}</span>
              </div>
            </div>
          )}

          {snapshot?.distanceToWaypoint != null && (
            <div style={styles.infoSection}>
              <div style={styles.infoRow}>
                <span style={styles.label}>Distance</span>
                <span style={styles.value}>{(snapshot.distanceToWaypoint * 1.852).toFixed(1)} km</span>
              </div>
            </div>
          )}
        </div>
      )}

      {/* Map Style Toggle */}
      <div style={styles.layerToggle}>
        <span style={{ fontSize: 11, color: 'var(--muted)' }}>+ SeaMarks</span>
      </div>
    </div>
  )
}

const styles = {
  container: {
    position: 'relative',
    flex: 1,
    overflow: 'hidden',
    borderRadius: 'var(--radius)',
  },
  mapBox: {
    width: '100%',
    height: '100%',
  },
  controls: {
    position: 'absolute',
    top: 12,
    right: 12,
    display: 'flex',
    flexDirection: 'column',
    gap: 6,
    zIndex: 1000,
  },
  infoPanel: {
    position: 'absolute',
    bottom: 12,
    left: 12,
    background: 'var(--glass-bg)',
    backdropFilter: 'blur(var(--glass-blur))',
    WebkitBackdropFilter: 'blur(var(--glass-blur))',
    border: '1px solid rgba(255, 255, 255, 0.1)',
    borderRadius: 'var(--radius-lg)',
    padding: '10px 12px',
    display: 'flex',
    flexDirection: 'column',
    gap: 6,
    fontSize: 12,
    color: 'var(--text)',
    zIndex: 500,
    maxWidth: 180,
    animation: 'slideInUp 0.3s ease-out',
  },
  infoSection: {
    display: 'flex',
    flexDirection: 'column',
    gap: 2,
  },
  infoRow: {
    display: 'flex',
    justifyContent: 'space-between',
    gap: 8,
  },
  label: {
    color: 'var(--muted)',
    fontWeight: 600,
    fontSize: 10,
  },
  value: {
    fontFamily: 'var(--font-mono)',
    fontWeight: 600,
    color: 'var(--accent)',
    textAlign: 'right',
  },
  layerToggle: {
    position: 'absolute',
    top: 60,
    right: 12,
    background: 'rgba(14, 165, 233, 0.1)',
    border: '1px solid rgba(14, 165, 233, 0.3)',
    borderRadius: 'var(--radius)',
    padding: '4px 8px',
    zIndex: 500,
  },
}
