import { useMemo, useCallback, useEffect, useRef } from 'react'
import { Map, useControl, useMap } from '@vis.gl/react-maplibre'
import { MapboxOverlay } from '@deck.gl/mapbox'
import { ScatterplotLayer } from '@deck.gl/layers'
import type { StyleSpecification } from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'
import type { AssetOrgCompat } from '../services/assetsApi'
import { typeColor } from './assetTypes'
import { hexToRgba } from '@common/components/map/mapUtils'

const BASE_STYLE: StyleSpecification = {
  version: 8,
  sources: {
    'carto-dark': {
      type: 'raster',
      tiles: [
        'https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
        'https://b.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
        'https://c.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}@2x.png',
      ],
      tileSize: 256,
      attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OSM</a> &copy; <a href="https://carto.com/">CARTO</a>',
    },
  },
  layers: [{ id: 'carto-dark-layer', type: 'raster', source: 'carto-dark' }],
}

// ── DeckGLOverlay ──────────────────────────────────────
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function DeckGLOverlay({ layers }: { layers: any[] }) {
  const overlay = useControl<MapboxOverlay>(() => new MapboxOverlay({ interleaved: true }))
  overlay.setProps({ layers })
  return null
}

// ── FlyTo Controller ────────────────────────────────────
function FlyToController({ selectedOrg }: { selectedOrg: AssetOrgCompat }) {
  const { current: map } = useMap()
  const prevIdRef = useRef<number | undefined>(undefined)

  useEffect(() => {
    if (!map) return
    if (prevIdRef.current !== undefined && prevIdRef.current !== selectedOrg.id) {
      map.flyTo({ center: [selectedOrg.lng, selectedOrg.lat], zoom: 10, duration: 800 })
    }
    prevIdRef.current = selectedOrg.id
  }, [map, selectedOrg])

  return null
}

interface AssetMapProps {
  organizations: AssetOrgCompat[]
  selectedOrg: AssetOrgCompat
  onSelectOrg: (o: AssetOrgCompat) => void
  regionFilter: string
  onRegionFilterChange: (v: string) => void
}

function AssetMap({
  organizations: orgs,
  selectedOrg,
  onSelectOrg,
  regionFilter,
  onRegionFilterChange,
}: AssetMapProps) {
  const handleClick = useCallback(
    (org: AssetOrgCompat) => {
      onSelectOrg(org)
    },
    [onSelectOrg],
  )

  const markerLayer = useMemo(() => {
    return new ScatterplotLayer({
      id: 'asset-orgs',
      data: orgs,
      getPosition: (d: AssetOrgCompat) => [d.lng, d.lat],
      getRadius: (d: AssetOrgCompat) => {
        const baseRadius = d.pinSize === 'hq' ? 14 : d.pinSize === 'lg' ? 10 : 7
        const isSelected = selectedOrg.id === d.id
        return isSelected ? baseRadius + 4 : baseRadius
      },
      getFillColor: (d: AssetOrgCompat) => {
        const tc = typeColor(d.type)
        const isSelected = selectedOrg.id === d.id
        return hexToRgba(isSelected ? tc.selected : tc.border, isSelected ? 229 : 178)
      },
      getLineColor: (d: AssetOrgCompat) => {
        const tc = typeColor(d.type)
        const isSelected = selectedOrg.id === d.id
        return hexToRgba(isSelected ? tc.selected : tc.border, isSelected ? 255 : 200)
      },
      getLineWidth: (d: AssetOrgCompat) => (selectedOrg.id === d.id ? 3 : 2),
      stroked: true,
      radiusMinPixels: 4,
      radiusMaxPixels: 20,
      radiusUnits: 'pixels',
      pickable: true,
      onClick: (info: { object?: AssetOrgCompat }) => {
        if (info.object) handleClick(info.object)
      },
      updateTriggers: {
        getRadius: [selectedOrg.id],
        getFillColor: [selectedOrg.id],
        getLineColor: [selectedOrg.id],
        getLineWidth: [selectedOrg.id],
      },
    })
  }, [orgs, selectedOrg, handleClick])

  return (
    <div className="w-full h-full relative">
      <Map
        initialViewState={{ longitude: 127.8, latitude: 35.9, zoom: 7 }}
        mapStyle={BASE_STYLE}
        className="w-full h-full"
        attributionControl={false}
      >
        <DeckGLOverlay layers={[markerLayer]} />
        <FlyToController selectedOrg={selectedOrg} />
      </Map>

      {/* Region filter overlay */}
      <div className="absolute top-3 left-3 z-[1000] flex gap-1">
        {[
          { value: 'all', label: '전체' },
          { value: '남해', label: '남해청' },
          { value: '서해', label: '서해청' },
          { value: '중부', label: '중부청' },
          { value: '동해', label: '동해청' },
          { value: '제주', label: '제주청' },
        ].map(r => (
          <button
            key={r.value}
            onClick={() => onRegionFilterChange(r.value)}
            className={`px-2.5 py-1.5 text-[10px] font-bold rounded font-korean transition-colors ${
              regionFilter === r.value
                ? 'bg-primary-cyan/20 text-primary-cyan border border-primary-cyan/40'
                : 'bg-bg-0/80 text-text-2 border border-border hover:bg-bg-hover/80'
            }`}
          >
            {r.label}
          </button>
        ))}
      </div>

      {/* Legend overlay */}
      <div className="absolute bottom-3 left-3 z-[1000] bg-bg-0/90 border border-border rounded-sm p-2.5 backdrop-blur-sm">
        <div className="text-[9px] text-text-3 font-bold mb-1.5 font-korean">범례</div>
        {[
          { color: '#06b6d4', label: '해경관할' },
          { color: '#3b82f6', label: '해경경찰서' },
          { color: '#22c55e', label: '파출소' },
          { color: '#a855f7', label: '관련기관' },
          { color: '#14b8a6', label: '해양환경공단' },
          { color: '#f59e0b', label: '업체' },
          { color: '#ec4899', label: '지자체' },
          { color: '#8b5cf6', label: '기름저장시설' },
          { color: '#0d9488', label: '정유사' },
          { color: '#64748b', label: '해군' },
          { color: '#6b7280', label: '기타' },
        ].map((item, i) => (
          <div key={i} className="flex items-center gap-1.5 mb-0.5 last:mb-0">
            <span className="w-2.5 h-2.5 rounded-full inline-block flex-shrink-0" style={{ background: item.color }} />
            <span className="text-[10px] text-text-2 font-korean">{item.label}</span>
          </div>
        ))}
      </div>
    </div>
  )
}

export default AssetMap
