<script lang="ts">
  import { enhance } from "$app/forms";
  import MapSlot from "$lib/components/MapSlot.svelte";
  import ElevationChart from "$lib/components/ElevationChart.svelte";
  import SpeedChart from "$lib/components/SpeedChart.svelte";
  import StatTile from "$lib/components/StatTile.svelte";
  import { mapState } from "$lib/map-state.svelte";
  import {
    fmtDate,
    fmtDistance,
    fmtDuration,
    fmtElapsed,
    fmtElevation,
    fmtSpeed,
  } from "$lib/format";

  let { data, form } = $props();
  const a = $derived(data.activity);

  const avgSpeed = $derived(
    a.moving_s && a.moving_s > 0 ? fmtSpeed(a.distance_m / a.moving_s) : null,
  );

  let editing = $state(false);
  let saving = $state(false);

  // create-segment panel: a distance slice of this track
  let segmenting = $state(false);
  let segStart = $state(0);
  let segEnd = $state(0);
  $effect(() => {
    segEnd = Math.round(a.distance_m);
  });

  // chart hover -> marker on the map at the matching track position
  function pointAt(d: number): [number, number] {
    const trackD = data.trackD;
    let lo = 0;
    let hi = trackD.length - 1;
    while (hi - lo > 1) {
      const mid = (lo + hi) >> 1;
      if (trackD[mid] < d) lo = mid;
      else hi = mid;
    }
    return data.latlngs[d - trackD[lo] < trackD[hi] - d ? lo : hi];
  }

  let hoverD = $state<number | null>(null);

  function chartHover(d: number | null) {
    hoverD = d;
    if (d === null) {
      mapState.setHoverPoint(null);
      return;
    }
    const [lat, lon] = pointAt(d);
    mapState.setHoverPoint({ lat, lon });
  }

  // chart click -> fly the map to that spot
  function chartSelect(d: number) {
    const [lat, lon] = pointAt(d);
    mapState.flyTo(lat, lon);
  }

  // the persistent map keeps the overview visible, dims the rest,
  // and animates toward this activity
  $effect(() => {
    mapState.setDetailTrack({
      id: a.id,
      name: a.name,
      username: a.username,
      type: a.type,
      date: a.date,
      distance_m: a.distance_m,
      latlngs: data.latlngs,
    });
    mapState.setHighlight(a.id);
    mapState.setPeaks(data.bagged);
    mapState.setFocus(JSON.parse(a.bounds));
    return () => mapState.reset();
  });
</script>

<svelte:head>
  <title>{a.name} · Streba</title>
</svelte:head>

<a class="back" href="/">← Overview</a>

<div class="head">
  {#if editing}
    <form
      class="edit-form"
      method="POST"
      action="?/update"
      use:enhance={() => {
        saving = true;
        return async ({ update, result }) => {
          saving = false;
          if (result.type === "success") editing = false;
          await update();
        };
      }}
    >
      <input
        class="edit-name"
        name="name"
        required
        maxlength="120"
        value={a.name}
        aria-label="Activity name"
      />
      <input
        class="edit-type"
        name="type"
        required
        maxlength="40"
        value={a.type}
        list="activity-types"
        aria-label="Activity type"
      />
      <datalist id="activity-types">
        {#each ["hike", "run", "ride", "ski", "climbing", "walk", "snowshoe"] as t (t)}
          <option value={t}></option>
        {/each}
      </datalist>
      <button class="btn" type="submit" disabled={saving}
        >{saving ? "Saving…" : "Save"}</button
      >
      <button class="btn ghost" type="button" onclick={() => (editing = false)}
        >Cancel</button
      >
      {#if form?.error}<span class="edit-error">{form.error}</span>{/if}
    </form>
  {:else}
    <div>
      <h1>
        {a.name}
        {#if data.canDelete}
          <button
            class="edit-btn"
            title="Edit name and type"
            aria-label="Edit name and type"
            onclick={() => (editing = true)}
          >
            ✎
          </button>
        {/if}
      </h1>
      <p class="page-sub">
        <a class="who" href="/users/{a.username}">{a.username}</a> · {fmtDate(
          a.date,
        )} ·
        <span class="type">{a.type}</span>
      </p>
    </div>
  {/if}
  {#if data.canDelete && !editing}
    <form
      method="POST"
      action="?/delete"
      use:enhance={({ cancel }) => {
        if (
          !confirm("Delete this activity? Peaks it reached stay in your list.")
        )
          cancel();
      }}
    >
      <button class="btn danger" type="submit">Delete</button>
    </form>
  {/if}
</div>

<div class="kpis">
  <StatTile label="Distance" value={fmtDistance(a.distance_m)} />
  <StatTile
    label="Ascent"
    value={fmtElevation(a.elev_gain_m)}
    detail="↓ {fmtElevation(a.elev_loss_m)}"
  />
  <StatTile
    label="Moving time"
    value={fmtDuration(a.moving_s ?? a.duration_s)}
    detail={a.duration_s ? `total ${fmtDuration(a.duration_s)}` : ""}
  />
  {#if avgSpeed}
    <StatTile label="Avg moving speed" value={avgSpeed} />
  {:else}
    <StatTile label="Highest point" value={fmtElevation(a.elev_max_m)} />
  {/if}
</div>

{#if data.bagged.length > 0}
  <div class="card bagged">
    ⛰ Peaks reached:
    {#each data.bagged as peak, i (peak.id)}{i > 0 ? ", " : " "}<strong
        >{peak.name}</strong
      >
      ({peak.elevation_m} m){/each}
  </div>
{/if}

{#if data.segmentEfforts.length > 0}
  <div class="card segments">
    <span class="seg-title">Segments on this activity:</span>
    {#each data.segmentEfforts as effort, i (effort.segment_id)}{i > 0
        ? " · "
        : " "}<a href="/segments/{effort.segment_id}">{effort.name}</a>{#if effort.elapsed_s !== null}&nbsp;({fmtElapsed(
          effort.elapsed_s,
        )}){/if}{/each}
  </div>
{/if}

{#if data.canCreateSegment}
  <div class="segment-create">
    {#if segmenting}
      <form class="card seg-form" method="POST" action="?/segment" use:enhance>
        <div class="seg-sliders">
          <label>
            Start · {fmtDistance(Math.min(segStart, segEnd))}
            <input
              type="range"
              name="start_d"
              min="0"
              max={Math.round(a.distance_m)}
              step="10"
              bind:value={segStart}
            />
          </label>
          <label>
            End · {fmtDistance(Math.max(segStart, segEnd))}
            <input
              type="range"
              name="end_d"
              min="0"
              max={Math.round(a.distance_m)}
              step="10"
              bind:value={segEnd}
            />
          </label>
          <span class="seg-len"
            >Length: {fmtDistance(Math.abs(segEnd - segStart))}</span
          >
        </div>
        <div class="seg-actions">
          <input name="name" placeholder="Segment name" required maxlength="80" />
          <button class="btn" type="submit">Create segment</button>
          <button class="btn ghost" type="button" onclick={() => (segmenting = false)}
            >Cancel</button
          >
        </div>
        {#if form?.error}<p class="edit-error">{form.error}</p>{/if}
      </form>
    {:else}
      <button class="btn ghost" onclick={() => (segmenting = true)}
        >＋ Create segment from this activity</button
      >
    {/if}
  </div>
{/if}

<MapSlot />

{#if data.profile.length > 1}
  <h2>Elevation profile</h2>
  <div class="card chart">
    <ElevationChart
      profile={data.profile}
      {hoverD}
      onhover={chartHover}
      onselect={chartSelect}
    />
    <div class="chart-meta">
      <span>Low {fmtElevation(a.elev_min_m)}</span>
      <span>High {fmtElevation(a.elev_max_m)}</span>
    </div>
  </div>
{/if}

{#if data.timed.length > 2}
  <h2>Speed</h2>
  <div class="card chart">
    <SpeedChart
      timed={data.timed}
      {hoverD}
      onhover={chartHover}
      onselect={chartSelect}
    />
  </div>
{/if}

<style>
  .back {
    display: inline-block;
    margin-bottom: 0.75rem;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--text-secondary);
    text-decoration: none;
    padding: 0.25rem 0.6rem;
    margin-left: -0.6rem;
    border-radius: 0.45rem;
  }
  .back:hover {
    background: var(--wash);
    color: var(--text-primary);
  }
  .head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
  }
  .edit-btn {
    border: none;
    background: none;
    font-size: 1rem;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0.15rem 0.4rem;
    border-radius: 0.4rem;
    vertical-align: middle;
  }
  .edit-btn:hover {
    background: var(--wash);
    color: var(--text-primary);
  }
  .edit-form {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    flex-wrap: wrap;
    width: 100%;
  }
  .edit-form input {
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 0.5rem;
    background: var(--surface-1);
    color: var(--text-primary);
    font: inherit;
  }
  .edit-name {
    flex: 1;
    min-width: 200px;
    font-weight: 600;
  }
  .edit-type {
    width: 120px;
    text-transform: capitalize;
  }
  .edit-form input:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
  }
  .edit-error {
    color: var(--critical);
    font-size: 0.85rem;
  }
  .type {
    text-transform: capitalize;
  }
  .segments {
    margin-top: 1rem;
    padding: 0.85rem 1.15rem;
    border-left: 3px solid var(--accent);
    color: var(--text-secondary);
  }
  .seg-title {
    font-weight: 600;
    color: var(--text-primary);
  }
  .segments a {
    color: var(--accent-strong);
    font-weight: 600;
    text-decoration: none;
  }
  .segments a:hover {
    text-decoration: underline;
  }
  .segment-create {
    margin-top: 1rem;
  }
  .seg-form {
    padding: 1.15rem;
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
  }
  .seg-sliders {
    display: flex;
    gap: 1.25rem;
    align-items: flex-end;
    flex-wrap: wrap;
  }
  .seg-sliders label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--text-secondary);
    flex: 1;
    min-width: 180px;
  }
  .seg-sliders input[type="range"] {
    accent-color: var(--accent);
  }
  .seg-len {
    font-size: 0.85rem;
    color: var(--text-primary);
    font-weight: 600;
    padding-bottom: 0.2rem;
  }
  .seg-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
  }
  .seg-actions input {
    flex: 1;
    min-width: 180px;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 0.5rem;
    background: var(--surface-1);
    color: var(--text-primary);
    font: inherit;
  }
  .who {
    font-weight: 600;
    color: var(--accent-strong);
    text-decoration: none;
  }
  .who:hover {
    text-decoration: underline;
  }
  .kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 0.75rem;
  }
  .bagged {
    margin-top: 1rem;
    padding: 0.85rem 1.15rem;
    border-left: 3px solid var(--good);
    color: var(--text-secondary);
  }
  .bagged strong {
    color: var(--text-primary);
  }
  .chart {
    padding: 1rem 1rem 0.5rem;
  }
  .chart-meta {
    display: flex;
    gap: 1.25rem;
    padding: 0.5rem 0.25rem 0.6rem;
    font-size: 0.8rem;
    color: var(--text-muted);
  }
</style>
