<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import XYZ from 'ol/source/XYZ'
import { fromLonLat } from 'ol/proj'
import { current } from '../services/weather'
import 'ol/ol.css'

const props = defineProps<{ dark: boolean }>()
const mapEl = ref<HTMLDivElement>()
let map: Map

const OVERLAYS = [
  { id: 'clouds',      label: 'Clouds',      icon: '☁️',  url: (ts: number) => `https://tilecache.rainviewer.com/v2/coverage/0/256/{z}/{x}/{y}/1/1_1.png` },
  { id: 'rain',        label: 'Rain',        icon: '🌧️',  url: (ts: number) => `https://tilecache.rainviewer.com/v2/radar/${ts}/256/{z}/{x}/{y}/4/1_1.png` },
  { id: 'wind',        label: 'Wind',        icon: '💨',  url: (_: number)  => `https://tile.openweathermap.org/map/wind_new/{z}/{x}/{y}.png?appid=demo` },
  { id: 'temp',        label: 'Temperature', icon: '🌡️',  url: (_: number)  => `https://tile.openweathermap.org/map/temp_new/{z}/{x}/{y}.png?appid=demo` },
  { id: 'pressure',    label: 'Pressure',    icon: '📊',  url: (_: number)  => `https://tile.openweathermap.org/map/pressure_new/{z}/{x}/{y}.png?appid=demo` },
]

const activeOverlays = ref<Set<string>>(new Set(['rain']))
const radarTs        = ref(Math.floor(Date.now() / 1000))
const overlayLayers  = new Map<string, TileLayer<XYZ>>()
let   radarInterval: ReturnType<typeof setInterval>

function buildBaseLayer(dark: boolean) {
  return new TileLayer({
    source: new XYZ({
      url: dark
        ? 'https://tiles.stadiamaps.com/tiles/alidade_smooth_dark/{z}/{x}/{y}.png'
        : 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}.png',
      attributions: '© Stadia Maps © OpenMapTiles © OpenStreetMap',
    }),
  })
}

function buildOverlayLayer(id: string): TileLayer<XYZ> {
  const def = OVERLAYS.find(o => o.id === id)!
  return new TileLayer({
    source: new XYZ({ url: def.url(radarTs.value), attributions: '' }),
    opacity: 0.6,
    zIndex: 10,
  })
}

function toggleOverlay(id: string) {
  if (activeOverlays.value.has(id)) {
    activeOverlays.value.delete(id)
    const layer = overlayLayers.get(id)
    if (layer) { map.removeLayer(layer); overlayLayers.delete(id) }
  } else {
    activeOverlays.value.add(id)
    const layer = buildOverlayLayer(id)
    overlayLayers.set(id, layer)
    map.addLayer(layer)
  }
}

onMounted(() => {
  const lat = (current.value.gps_lat as number) || 0
  const lon = (current.value.gps_lon as number) || 0

  map = new Map({
    target: mapEl.value!,
    layers: [buildBaseLayer(props.dark)],
    view: new View({
      center: fromLonLat([lon, lat]),
      zoom: 9,
    }),
    controls: [],
  })

  // Add default active overlays
  for (const id of activeOverlays.value) {
    const layer = buildOverlayLayer(id)
    overlayLayers.set(id, layer)
    map.addLayer(layer)
  }

  // Refresh radar every 5 min
  radarInterval = setInterval(() => {
    radarTs.value = Math.floor(Date.now() / 1000)
    const layer = overlayLayers.get('rain')
    if (layer) {
      layer.setSource(new XYZ({ url: OVERLAYS.find(o => o.id === 'rain')!.url(radarTs.value) }))
    }
  }, 5 * 60 * 1000)
})

onUnmounted(() => clearInterval(radarInterval))

watch(() => props.dark, (dark) => {
  const layers = map.getLayers()
  layers.setAt(0, buildBaseLayer(dark))
})
</script>

<style scoped lang="scss">
.map-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 12px;
  overflow: hidden;
}

.map-el {
  width: 100%;
  height: 100%;
}

.overlay-toggles {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 8px;
  z-index: 100;
  background: var(--surface);
  border-radius: 99px;
  padding: 6px 10px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.2);
}

.overlay-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border-radius: 99px;
  border: 1.5px solid var(--border);
  background: transparent;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.15s;
  white-space: nowrap;

  &.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
  }

  &:hover:not(.active) {
    background: var(--hover);
  }
}
</style>

<template>
  <div class="map-wrap">
    <div ref="mapEl" class="map-el" />
    <div class="overlay-toggles">
      <button
        v-for="o in OVERLAYS"
        :key="o.id"
        class="overlay-btn"
        :class="{ active: activeOverlays.has(o.id) }"
        @click="toggleOverlay(o.id)"
      >
        {{ o.icon }} {{ o.label }}
      </button>
    </div>
  </div>
</template>
