<script lang="ts">
  import { onMount } from "svelte";
  import { browser } from "$app/environment";
  import { env } from "$env/dynamic/public";
  import type { WindMapBlockData } from "$lib/block-types";
  import type { WindArea } from "$lib/windkarte";
  import WindAreaPanel from "$lib/components/WindAreaPanel.svelte";
  import { useTranslate, T } from "$lib/translations";
  import { getBlockLayoutClasses } from "$lib/block-layout";

  const t = useTranslate();

  let { block }: { block: WindMapBlockData } = $props();

  const layoutClasses = $derived(getBlockLayoutClasses(block.layout));

  const CMS_BASE = (
    env.PUBLIC_CMS_URL || "http://localhost:3000"
  ).replace(/\/$/, "");

let areas = $state<WindArea[]>([]);
  let selectedArea = $state<WindArea | null>(null);
  let selectedCenter = $state<[number, number] | null>(null);
  let mapReady = $state(false);
  let initialGebietsNr = $state<string | null>(null);
  let resetMap: (() => void) | null = null;
  let hiddenStatuses = $state<string[]>(["rechtskraeftig"]);
  let hiddenRings = $state<string[]>([]);
  let mapActive = $state(false);
  let blockEl: HTMLDivElement;

  function toggleStatus(status: string) {
    hiddenStatuses = hiddenStatuses.includes(status)
      ? hiddenStatuses.filter((s) => s !== status)
      : [...hiddenStatuses, status];
  }

  function toggleRing(ring: string) {
    hiddenRings = hiddenRings.includes(ring)
      ? hiddenRings.filter((r) => r !== ring)
      : [...hiddenRings, ring];
  }

  const MapComponent = browser
    ? import("$lib/components/WindkarteMap.svelte").then((m) => m.default)
    : null;

  function handleSelect(area: WindArea | null, center: [number, number] | null = null) {
    selectedArea = area;
    selectedCenter = center;
    if (browser) {
      if (area) {
        history.replaceState(null, "", location.pathname + location.search + "#" + encodeURIComponent(area.gebiets_nr));
      } else {
        history.replaceState(null, "", location.pathname + location.search);
      }
    }
  }

  onMount(async () => {
    const hash = window.location.hash.slice(1);
    if (hash) initialGebietsNr = decodeURIComponent(hash);

    try {
      const slugs = (block.areas ?? [])
        .map((a) => (typeof a === "string" ? a : a._slug))
        .filter(Boolean);

      if (slugs.length > 0) {
        const results = await Promise.all(
          slugs.map((slug) =>
            fetch(`${CMS_BASE}/api/content/wind_area/${slug}`, {
              signal: AbortSignal.timeout(6_000),
            }).then((r) => (r.ok ? r.json() : null))
          )
        );
        areas = results.filter((r): r is WindArea => r !== null);
      } else {
        const res = await fetch(`${CMS_BASE}/api/content/wind_area?_limit=100`, {
          signal: AbortSignal.timeout(6_000),
        });
        if (res.ok) {
          const data = await res.json();
          areas = data.items ?? [];
        }
      }
    } catch {
      // Map renders without CMS metadata — GeoJSON tooltips still work
    }
    mapReady = true;
    if (initialGebietsNr) {
      setTimeout(() => blockEl?.scrollIntoView({ behavior: "smooth", block: "start" }), 100);
    }
  });
</script>

<div
  bind:this={blockEl}
  class="wind-map-block {layoutClasses}"
  data-block="WindMap"
  data-block-type="wind_map"
  data-block-slug={block._slug}
>
  {#if block.title || block.subtitle}
    <div class="mb-4">
      {#if block.title}
        <h2 class="text-xl font-semibold text-stein-800">{block.title}</h2>
      {/if}
      {#if block.subtitle}
        <p class="mt-0.5 text-sm text-stein-500">{block.subtitle}</p>
      {/if}
    </div>
  {/if}

  <div class="map-container relative overflow-hidden rounded-xl border border-stein-200 shadow-sm">
    <!-- Reset button -->
    {#if resetMap}
      <button
        onclick={() => { resetMap?.(); handleSelect(null); }}
        class="pointer-events-auto absolute top-2.5 right-2.5 z-[500] rounded-md bg-white/90 p-1.5 shadow-md text-stein-500 hover:text-stein-800 hover:bg-white transition-colors"
        aria-label={t(T.windkarte_reset_aria)}
        title={t(T.windkarte_reset_aria)}
      >
        <svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/>
          <path d="M3 3v5h5"/>
        </svg>
      </button>
    {/if}

    {#if browser && MapComponent && mapReady}
      {#await MapComponent then Map}
        <Map
          {areas}
          {initialGebietsNr}
          {hiddenStatuses}
          {hiddenRings}
          onselect={handleSelect}
          onready={(ctrl) => { resetMap = ctrl.reset; }}
        />
      {/await}
    {:else}
      <div class="flex h-full items-center justify-center bg-stein-50 text-stein-400 text-sm">
        {t(T.windkarte_loading)}
      </div>
    {/if}

    <!-- Mobile tap-to-activate overlay (touch devices only) -->
    {#if !mapActive}
      <button
        type="button"
        onclick={() => { mapActive = true; }}
        class="map-activate-overlay"
        aria-label={t(T.windkarte_tap_to_activate)}
      >
        <span class="map-activate-label">
          <svg class="size-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <path d="M9 11l3 3L22 4"/>
            <path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/>
          </svg>
          {t(T.windkarte_tap_to_activate)}
        </span>
      </button>
    {/if}

    <!-- Panel: bottom-sheet on mobile, side-panel on sm+ -->
    <div class="panel-slide {selectedArea ? 'open' : ''}" style="pointer-events: none; z-index: 1001;">
      <WindAreaPanel
        area={selectedArea}
        center={selectedCenter}
        onclose={() => handleSelect(null)}
      />
    </div>
  </div>

  <!-- Legend -->
  <div class="mt-2 flex flex-wrap gap-x-5 gap-y-1.5 text-xs text-stein-400">
    {#each [
      { status: "rechtskraeftig", color: "#2d7a45", label: t(T.windkarte_legend_rechtskraeftig) },
      { status: "entwurf_2",      color: "#b08a52", label: t(T.windkarte_legend_entwurf_2) },
    ] as item}
      <button
        type="button"
        onclick={() => toggleStatus(item.status)}
        class="flex items-center gap-1.5 transition-opacity cursor-pointer select-none
               {hiddenStatuses.includes(item.status) ? 'opacity-35' : 'opacity-100'}"
        title={hiddenStatuses.includes(item.status) ? 'Einblenden' : 'Ausblenden'}
      >
        <span class="inline-block size-2.5 rounded-sm shrink-0" style="background:{item.color}; opacity:.7"></span>
        <span class="{hiddenStatuses.includes(item.status) ? 'line-through' : ''}">{item.label}</span>
      </button>
    {/each}
    <span class="flex items-center gap-x-3 gap-y-1 flex-wrap text-stein-300">
      <span class="text-stein-400">{t(T.windkarte_legend_distances)}</span>
      {#each [{ color: "#e35651", label: "200 m" }, { color: "#b08a52", label: "600 m" }, { color: "#436e85", label: "1 km" }] as ring}
        <span class="flex items-center gap-1.5">
          <span class="dashed-line" style="border-color:{ring.color}"></span>
          {ring.label}
        </span>
      {/each}
      {#each [{ key: "2km", color: "#5e6fa3", label: "2 km" }, { key: "5km", color: "#8a567a", label: "5 km" }] as ring}
        <button
          type="button"
          onclick={() => toggleRing(ring.key)}
          class="flex items-center gap-1.5 cursor-pointer select-none transition-opacity
                 {hiddenRings.includes(ring.key) ? 'opacity-35' : 'opacity-100'}"
          title={hiddenRings.includes(ring.key) ? 'Einblenden (alle Gebiete)' : 'Ausblenden'}
        >
          <span class="dashed-line {hiddenRings.includes(ring.key) ? 'opacity-40' : ''}" style="border-color:{ring.color}"></span>
          <span class="{hiddenRings.includes(ring.key) ? 'line-through' : ''}">{ring.label}</span>
        </button>
      {/each}
    </span>
  </div>
</div>

<style>
  .map-container {
    height: clamp(460px, 75vh, 620px);
  }

  /* Panel: mobile = bottom sheet, sm+ = right side panel */
  .panel-slide {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 52%;
    transform: translateY(100%);
    transition: transform 300ms ease-in-out;
  }
  .panel-slide.open {
    transform: translateY(0);
    pointer-events: auto !important;
  }
  @media (min-width: 640px) {
    .panel-slide {
      top: 0;
      left: auto;
      right: 0;
      bottom: 0;
      height: auto;
      width: 18rem;
      transform: translateX(100%);
    }
    .panel-slide.open {
      transform: translateX(0);
    }
  }

  /* Touch-only overlay — hidden on hover-capable devices (desktop/mouse) */
  .map-activate-overlay {
    display: none;
  }
  @media (hover: none) {
    .map-activate-overlay {
      display: flex;
      position: absolute;
      inset: 0;
      z-index: 490;
      align-items: center;
      justify-content: center;
      background: rgba(0, 0, 0, 0.25);
      cursor: pointer;
      border: none;
      padding: 0;
    }
  }
  .map-activate-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: rgba(255, 255, 255, 0.92);
    border-radius: 0.5rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.18);
    color: #333735;
    font-size: 0.875rem;
    font-weight: 500;
    padding: 0.625rem 1rem;
    pointer-events: none;
  }

  .dashed-line {
    display: inline-block;
    width: 18px;
    height: 0;
    border-top: 2px dashed;
    vertical-align: middle;
  }
</style>
