<script lang="ts">
  import { onMount, onDestroy } from 'svelte';
  import maplibregl from 'maplibre-gl';
  import 'maplibre-gl/dist/maplibre-gl.css';
  import { formatDistance, formatDate, formatElapsed, sportIcon } from '../lib/format';

  export let base: string = '/';
  export let segmentId: string = '';

  interface Segment {
    id: string;
    name: string;
    sport: string | null;
    distance_m: number;
    polyline: [number, number][];
    created_by: string;
    created_at: string;
  }

  interface Effort {
    activity_id: string;
    started_at: string;
    elapsed_s: number;
    avg_speed_kmh: number | null;
    avg_hr_bpm: number | null;
    avg_power_w: number | null;
    np_power_w: number | null;
  }

  type SortKey = 'started_at' | 'elapsed_s' | 'avg_speed_kmh' | 'avg_hr_bpm' | 'avg_power_w' | 'np_power_w';

  let segment: Segment | null = null;
  let efforts: Effort[] = [];
  let loading = true;
  let loggedIn = true;
  let mapEl: HTMLDivElement;
  let map: any;
  let mapReady = false;
  let retriggering = false;
  let retriggerMsg: string | null = null;
  let sortKey: SortKey = 'elapsed_s';
  let sortDir: 1 | -1 = 1;

  $: prElapsed = efforts.length ? Math.min(...efforts.map(e => e.elapsed_s)) : null;

  $: sortedEfforts = [...efforts].sort((a, b) => {
    const av = a[sortKey], bv = b[sortKey];
    if (av == null && bv == null) return 0;
    if (av == null) return 1;
    if (bv == null) return -1;
    return av < bv ? -sortDir : av > bv ? sortDir : 0;
  });

  function setSort(key: SortKey) {
    if (sortKey === key) sortDir = sortDir === 1 ? -1 : 1;
    else { sortKey = key; sortDir = 1; }
  }

  function delta(elapsed: number): number {
    return prElapsed != null ? elapsed - prElapsed : 0;
  }

  function formatDelta(d: number): string {
    if (d === 0) return 'PR';
    const abs = Math.abs(d);
    const m = Math.floor(abs / 60);
    const s = abs % 60;
    const sign = d > 0 ? '+' : '−';
    return m > 0 ? `${sign}${m}m${s.toString().padStart(2, '0')}s` : `${sign}${s}s`;
  }

  onMount(async () => {
    const [segRes, effRes] = await Promise.allSettled([
      fetch(`/api/segments/${segmentId}`, { credentials: 'include' }),
      fetch(`/api/segments/${segmentId}/efforts`, { credentials: 'include' }),
    ]);

    if (segRes.status === 'fulfilled' && segRes.value.ok) {
      segment = await segRes.value.json();
    }
    if (effRes.status === 'fulfilled') {
      if (effRes.value.status === 401) {
        loggedIn = false;
      } else if (effRes.value.ok) {
        efforts = await effRes.value.json();
      }
    }

    loading = false;
    if (segment) setTimeout(initMap, 0);
  });

  onDestroy(() => map?.remove());

  function initMap() {
    if (!mapEl || !segment) return;
    const lons = segment.polyline.map(([, lon]) => lon);
    const lats = segment.polyline.map(([lat]) => lat);

    map = new maplibregl.Map({
      container: mapEl,
      style: 'https://tiles.openfreemap.org/styles/positron',
      bounds: [[Math.min(...lons), Math.min(...lats)], [Math.max(...lons), Math.max(...lats)]],
      fitBoundsOptions: { padding: 60 },
      attributionControl: false,
    });
    map.addControl(new maplibregl.AttributionControl({ compact: true }), 'bottom-right');

    map.on('load', () => {
      map.addSource('seg', {
        type: 'geojson',
        lineMetrics: true,
        data: {
          type: 'Feature',
          geometry: {
            type: 'LineString',
            coordinates: segment!.polyline.map(([lat, lon]) => [lon, lat]),
          },
        },
      });
      map.addLayer({ id: 'seg-line', type: 'line', source: 'seg',
        layout: { 'line-cap': 'round', 'line-join': 'round' },
        paint: {
          'line-gradient': ['interpolate', ['linear'], ['line-progress'], 0, '#22c55e', 1, '#ef4444'],
          'line-width': 5,
        } });

      // Start/end markers
      const start = segment!.polyline[0];
      const end   = segment!.polyline[segment!.polyline.length - 1];
      for (const [pt, label, color] of [[start, 'S', '#22c55e'], [end, 'E', '#ef4444']] as const) {
        const el = document.createElement('div');
        el.style.cssText = `width:20px;height:20px;border-radius:50%;background:${color};color:#fff;font-size:10px;font-weight:700;display:flex;align-items:center;justify-content:center;border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.4)`;
        el.textContent = label;
        new maplibregl.Marker({ element: el }).setLngLat([pt[1], pt[0]]).addTo(map);
      }

      mapReady = true;
    });
  }

  async function retrigger() {
    retriggering = true;
    retriggerMsg = null;
    try {
      const r = await fetch(`/api/segments/${segmentId}/detect`, {
        method: 'POST', credentials: 'include',
      });
      const d = await r.json();
      if (r.ok) {
        retriggerMsg = `Found ${d.efforts_found} effort${d.efforts_found !== 1 ? 's' : ''}.`;
        // Reload efforts
        const er = await fetch(`/api/segments/${segmentId}/efforts`, { credentials: 'include' });
        if (er.ok) efforts = await er.json();
      } else {
        retriggerMsg = d.detail ?? 'Detection failed.';
      }
    } catch {
      retriggerMsg = 'Could not reach server.';
    }
    retriggering = false;
  }
</script>

<div class="max-w-3xl mx-auto px-4 py-6">
  <!-- Back -->
  <a href="{base}segments/" class="text-zinc-500 hover:text-white transition-colors text-sm">← Segments</a>

  {#if loading}
    <div class="mt-6 space-y-4">
      <div class="h-7 w-48 bg-zinc-800 rounded animate-pulse"></div>
      <div class="h-64 bg-zinc-800 rounded-xl animate-pulse"></div>
    </div>

  {:else if !segment}
    <p class="mt-6 text-red-400 text-sm">Segment not found.</p>

  {:else}
    <!-- Title + metadata -->
    <div class="mt-4 mb-4 flex items-start gap-3">
      {#if segment.sport}
        <span class="text-2xl mt-0.5">{sportIcon(segment.sport as any)}</span>
      {/if}
      <div>
        <h1 class="text-2xl font-bold text-white">{segment.name}</h1>
        <p class="text-sm text-zinc-500 mt-0.5">
          {formatDistance(segment.distance_m)}
          {#if segment.sport} · {segment.sport}{/if}
          · by {segment.created_by}
          · {formatDate(segment.created_at)}
        </p>
      </div>
    </div>

    <!-- Map -->
    <div class="rounded-xl overflow-hidden mb-6" style="height: 280px;">
      <div bind:this={mapEl} class="w-full h-full"></div>
    </div>

    <!-- Efforts -->
    <div class="flex items-center justify-between mb-3">
      <h2 class="text-base font-semibold text-white">Your efforts</h2>
      {#if loggedIn}
        <div class="flex items-center gap-3">
          {#if retriggerMsg}
            <span class="text-xs text-zinc-400">{retriggerMsg}</span>
          {/if}
          <button
            on:click={retrigger}
            disabled={retriggering}
            class="text-xs px-3 py-1.5 rounded-lg border border-zinc-700 text-zinc-400 hover:border-zinc-500 hover:text-white transition-colors disabled:opacity-40"
          >{retriggering ? 'Scanning…' : 'Rescan activities'}</button>
        </div>
      {/if}
    </div>

    {#if !loggedIn}
      <p class="text-zinc-500 text-sm">
        <a href="{base}login/" class="text-blue-400 hover:text-blue-300">Log in</a> to see your efforts on this segment.
      </p>

    {:else if efforts.length === 0}
      <div class="bg-zinc-900 rounded-xl border border-zinc-800 p-6 text-center">
        <p class="text-zinc-500 text-sm">No efforts yet.</p>
        <p class="text-zinc-600 text-xs mt-1">Upload an activity that passes through this segment, or use "Rescan activities" to check existing ones.</p>
      </div>

    {:else}
      <div class="bg-zinc-900 rounded-xl border border-zinc-800 overflow-hidden">
        <table class="w-full text-sm">
          <thead class="border-b border-zinc-800">
            <tr class="text-left text-zinc-500 text-xs">
              <th class="px-4 py-2">
                <button class="hover:text-white transition-colors" class:text-white={sortKey==='started_at'} on:click={() => setSort('started_at')}>
                  Date{sortKey==='started_at' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
                </button>
              </th>
              <th class="px-4 py-2">
                <button class="hover:text-white transition-colors" class:text-white={sortKey==='elapsed_s'} on:click={() => setSort('elapsed_s')}>
                  Time{sortKey==='elapsed_s' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
                </button>
              </th>
              <th class="px-4 py-2">Δ PR</th>
              <th class="px-4 py-2 hidden sm:table-cell">
                <button class="hover:text-white transition-colors" class:text-white={sortKey==='avg_speed_kmh'} on:click={() => setSort('avg_speed_kmh')}>
                  Avg speed{sortKey==='avg_speed_kmh' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
                </button>
              </th>
              <th class="px-4 py-2 hidden sm:table-cell">
                <button class="hover:text-white transition-colors" class:text-white={sortKey==='avg_hr_bpm'} on:click={() => setSort('avg_hr_bpm')}>
                  Avg HR{sortKey==='avg_hr_bpm' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
                </button>
              </th>
              <th class="px-4 py-2 hidden md:table-cell">
                <button class="hover:text-white transition-colors" class:text-white={sortKey==='avg_power_w'} on:click={() => setSort('avg_power_w')}>
                  Avg power{sortKey==='avg_power_w' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
                </button>
              </th>
              <th class="px-4 py-2 hidden md:table-cell">
                <button class="hover:text-white transition-colors" class:text-white={sortKey==='np_power_w'} on:click={() => setSort('np_power_w')}>
                  NP{sortKey==='np_power_w' ? (sortDir===1 ? ' ↑' : ' ↓') : ''}
                </button>
              </th>
            </tr>
          </thead>
          <tbody>
            {#each sortedEfforts as e (e.activity_id + e.started_at)}
              {@const d = delta(e.elapsed_s)}
              {@const isPR = d === 0}
              <tr
                class="border-b border-zinc-800/50 hover:bg-zinc-800/50 transition-colors"
                class:bg-green-950={isPR}
                class:hover:bg-green-900={isPR}
              >
                <td class="px-4 py-2">
                  <a href="{base}activity/{e.activity_id}/" class="text-blue-400 hover:text-blue-300 transition-colors">
                    {formatDate(e.started_at)}
                  </a>
                </td>
                <td class="px-4 py-2 text-white font-mono">{formatElapsed(e.elapsed_s)}</td>
                <td class="px-4 py-2 font-medium text-xs"
                    class:text-green-400={isPR}
                    class:text-zinc-400={!isPR}>
                  {formatDelta(d)}
                </td>
                <td class="px-4 py-2 text-zinc-300 hidden sm:table-cell">
                  {e.avg_speed_kmh != null ? `${e.avg_speed_kmh.toFixed(1)} km/h` : '—'}
                </td>
                <td class="px-4 py-2 text-zinc-300 hidden sm:table-cell">
                  {e.avg_hr_bpm != null ? `${e.avg_hr_bpm} bpm` : '—'}
                </td>
                <td class="px-4 py-2 text-zinc-300 hidden md:table-cell">
                  {e.avg_power_w != null ? `${e.avg_power_w} W` : '—'}
                </td>
                <td class="px-4 py-2 text-zinc-300 hidden md:table-cell">
                  {e.np_power_w != null ? `${e.np_power_w} W` : '—'}
                </td>
              </tr>
            {/each}
          </tbody>
        </table>
      </div>
    {/if}
  {/if}
</div>
