<script lang="ts">
  import { onMount } from 'svelte';
  import type { AthleteJson, BASIndex, ActivitySummary } from '../lib/types';
  import MmpChart from './MmpChart.svelte';
  import RecordsView from './RecordsView.svelte';
  import AthleteDrawer from './AthleteDrawer.svelte';
  import Explore from './Explore.svelte';
  import NerdCorner from './NerdCorner.svelte';
  import { isUnlisted, formatElapsed, formatDistance, sportIcon } from '../lib/format';
  import { loadIndex, loadAthlete } from '../lib/dataloader';

  export let base: string = '/';
  /** Explicit index URL for multi-user per-user pages (user's shard). */
  export let indexUrl: string = '';
  /** Explicit athlete.json URL for multi-user per-user pages. */
  export let athleteUrl: string = '';
  /** Handle whose segment summary to show. Parsed from athleteUrl if blank. */
  export let handle: string = '';

  let athlete: AthleteJson | null = null;
  let activities:    ActivitySummary[] = [];
  let allActivities: ActivitySummary[] = [];
  let loading = true;
  let error: string | null = null;
  let drawerOpen = false;

  type Tab = 'power' | 'records' | 'segments' | 'profile' | 'explore' | 'nerd';
  let activeTab: Tab = 'power';
  let mounted = false;
  let isOwner = false;

  interface SegmentSummaryItem {
    segment: { id: string; name: string; sport: string | null; distance_m: number };
    best_elapsed_s: number;
    best_activity_id: string;
    effort_count: number;
  }
  interface SegmentEffort {
    activity_id: string;
    started_at: string;
    elapsed_s: number;
  }
  let segmentSummary: SegmentSummaryItem[] = [];
  let segmentsLoading = false;
  let segmentsFetched = false;
  let segmentsHandle = '';
  let rescanning = false;
  let rescanMsg: string | null = null;
  let expandedId: string | null = null;
  let effortsBySegment: Record<string, SegmentEffort[]> = {};
  let loadingEfforts: Record<string, boolean> = {};

  async function toggleSegment(id: string) {
    if (expandedId === id) { expandedId = null; return; }
    expandedId = id;
    if (!effortsBySegment[id] && !loadingEfforts[id]) {
      loadingEfforts = { ...loadingEfforts, [id]: true };
      try {
        const r = await fetch(`/api/segments/${id}/efforts`, { credentials: 'include' });
        if (r.ok) effortsBySegment = { ...effortsBySegment, [id]: await r.json() };
      } catch { /* ignore */ }
      loadingEfforts = { ...loadingEfforts, [id]: false };
    }
  }

  const editUrl = import.meta.env.PUBLIC_EDIT_URL ?? '';
  const editEnabled = editUrl !== '' || import.meta.env.PUBLIC_EDIT_ENABLED === 'true';

  $: if (mounted) {
    const params = new URLSearchParams(window.location.search);
    if (activeTab === 'power') params.delete('tab'); else params.set('tab', activeTab);
    const qs = params.toString();
    history.replaceState(null, '', qs ? `?${qs}` : window.location.pathname);
  }

  $: if (activeTab === 'segments' && segmentsHandle && !segmentsFetched && !segmentsLoading) {
    segmentsLoading = true;
    segmentsFetched = true;
    fetch(`/api/users/${segmentsHandle}/segment_summary`)
      .then(r => r.ok ? r.json() : [])
      .then(d => { segmentSummary = d; })
      .catch(() => {})
      .finally(() => { segmentsLoading = false; });
  }

  onMount(async () => {
    const w = window as any;
    if (w.__bincioMe !== undefined) {
      isOwner = w.__bincioMe === handle;
    } else {
      // Multi-user: __bincioMe is set asynchronously by /api/me in Base.astro.
      // Listen for the event so owner-only tabs appear without a hard refresh.
      window.addEventListener('bincio:me', (e: Event) => {
        isOwner = (e as CustomEvent<string>).detail === handle;
      }, { once: true });
    }
    const TABS: Tab[] = ['power', 'records', 'segments', 'profile', 'explore', 'nerd'];
    const rawTab = new URLSearchParams(window.location.search).get('tab');
    const resolved = TABS.includes(rawTab as Tab) ? (rawTab as Tab) : 'power';
    activeTab = (resolved === 'explore' && !isOwner) ? 'power' : resolved;
    mounted = true;

    // Resolve handle for the segments endpoint
    if (handle) {
      segmentsHandle = handle;
    } else if (athleteUrl) {
      // Parse from e.g. "/data/ccbas/_merged/athlete.json"
      const m = athleteUrl.match(/\/data\/([^/]+)\//);
      if (m) segmentsHandle = m[1];
    }
    if (!segmentsHandle) {
      // Fall back to /api/me for the self-athlete page
      try {
        const r = await fetch('/api/me', { credentials: 'include' });
        if (r.ok) { const u = await r.json(); segmentsHandle = u.handle ?? ''; }
      } catch { /* ignore */ }
    }
    try {
      const [athleteData, index] = await Promise.all([
        loadAthlete(import.meta.env.BASE_URL, athleteUrl || undefined),
        loadIndex(import.meta.env.BASE_URL, indexUrl || undefined),
      ]);
      // Static file may not exist yet if the background rebuild hasn't finished — fall back to API
      let resolvedAthlete = athleteData as AthleteJson | null;
      if (!resolvedAthlete && editEnabled) {
        try {
          const r = await fetch('/api/athlete', { credentials: 'include' });
          if (r.ok) resolvedAthlete = await r.json() as AthleteJson;
        } catch { /* ignore */ }
      }
      athlete = resolvedAthlete;
      allActivities = index.activities.filter(a => !isUnlisted(a.privacy));
      activities    = allActivities.filter(a => a.mmp);
    } catch (e: any) {
      error = e.message;
    } finally {
      loading = false;
    }
  });

  async function onSaved() {
    // Try static file first; fall back to API (works before the background rebuild finishes)
    const staticUrl = athleteUrl || `${import.meta.env.BASE_URL}data/athlete.json`;
    let res = await fetch(`${staticUrl}?t=${Date.now()}`);
    if (!res.ok) res = await fetch('/api/athlete', { credentials: 'include' });
    if (res.ok) athlete = await res.json() as AthleteJson;
    drawerOpen = false;
  }

  function fmtZone(zones: [number, number][], i: number): string {
    const [lo, hi] = zones[i];
    return hi >= 9000 ? `${lo}+ W` : `${lo}–${hi} W`;
  }
  function fmtHrZone(zones: [number, number][], i: number): string {
    const [lo, hi] = zones[i];
    return hi >= 900 ? `${lo}+ bpm` : `${lo}–${hi} bpm`;
  }

  const ALL_TABS: { key: Tab; label: string; ownerOnly?: boolean }[] = [
    { key: 'power',    label: 'Power Curve' },
    { key: 'records',  label: 'Records'     },
    { key: 'segments', label: 'Segments'    },
    { key: 'profile',  label: 'Profile'     },
    { key: 'explore',  label: 'Explore',    ownerOnly: true },
    { key: 'nerd',     label: 'Nerd Corner', ownerOnly: true },
  ];
  $: TABS = ALL_TABS.filter(t => !t.ownerOnly || isOwner);
</script>

{#if loading}
  <p class="text-zinc-400 text-sm">Loading…</p>
{:else if error}
  <p class="text-red-400 text-sm">{error}</p>
{:else if !athlete}
  <div class="text-zinc-400 text-sm space-y-3">
    <p>No athlete profile yet.</p>
    {#if editEnabled}
      <button
        on:click={() => drawerOpen = true}
        class="px-3 py-1.5 text-xs border border-zinc-700 hover:border-zinc-500 text-zinc-400 hover:text-white rounded-md transition-colors"
      >Create profile</button>
    {/if}
  </div>
{:else}

  <!-- Header row: tabs + edit button -->
  <div class="flex items-center justify-between mb-6 border-b border-zinc-800 pb-0">
    <nav class="flex gap-0">
      {#each TABS as tab}
        <button
          on:click={() => activeTab = tab.key}
          class="px-4 py-3 text-sm font-medium border-b-2 transition-colors -mb-px"
          class:border-blue-500={activeTab === tab.key}
          class:text-white={activeTab === tab.key}
          class:border-transparent={activeTab !== tab.key}
          class:text-zinc-500={activeTab !== tab.key}
          class:hover:text-zinc-300={activeTab !== tab.key}
        >{tab.label}</button>
      {/each}
    </nav>
    {#if editEnabled}
      <button
        on:click={() => drawerOpen = true}
        class="mb-2 px-3 py-1.5 text-xs border border-zinc-700 hover:border-zinc-500 text-zinc-400 hover:text-white rounded-md transition-colors"
      >Edit profile</button>
    {/if}
  </div>

  <!-- Power Curve tab -->
  {#if activeTab === 'power'}
    {#if athlete.power_curve.all_time}
      <div class="bg-zinc-900 rounded-xl p-4 border border-zinc-800">
        <MmpChart {athlete} {activities} {base} />
      </div>
    {:else}
      <p class="text-zinc-500 text-sm">No power data found. Make sure your activities include power meter data.</p>
    {/if}

  <!-- Records tab -->
  {:else if activeTab === 'records'}
    <RecordsView {athlete} {base} />

  <!-- Segments tab -->
  {:else if activeTab === 'segments'}
    <div class="flex items-center justify-between mb-4">
      <span></span>
      <div class="flex items-center gap-3">
        {#if rescanMsg}<span class="text-xs text-zinc-400">{rescanMsg}</span>{/if}
        <button
          on:click={async () => {
            rescanning = true; rescanMsg = null;
            try {
              const r = await fetch('/api/me/segment-rescan', { method: 'POST', credentials: 'include' });
              const d = await r.json();
              if (r.ok) {
                rescanMsg = `Found ${d.efforts_found} effort${d.efforts_found !== 1 ? 's' : ''}.`;
                segmentSummary = [];
                segmentsFetched = false;
              } else rescanMsg = d.detail ?? 'Rescan failed.';
            } catch { rescanMsg = 'Could not reach server.'; }
            rescanning = false;
          }}
          disabled={rescanning}
          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"
        >{rescanning ? 'Scanning…' : 'Rescan all activities'}</button>
      </div>
    </div>
    {#if segmentsLoading}
      <p class="text-zinc-500 text-sm">Loading…</p>
    {:else if segmentSummary.length === 0}
      <p class="text-zinc-500 text-sm">No segment efforts yet. Use "Rescan all activities" to detect efforts from existing activities.</p>
    {: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">Segment</th>
              <th class="px-4 py-2 hidden sm:table-cell">Distance</th>
              <th class="px-4 py-2">Best time</th>
              <th class="px-4 py-2 text-right pr-4">Efforts</th>
            </tr>
          </thead>
          <tbody>
            {#each segmentSummary as row (row.segment.id)}
              <!-- Summary row -->
              <tr
                class="border-b border-zinc-800/50 hover:bg-zinc-800/40 transition-colors cursor-pointer select-none"
                class:bg-zinc-800={expandedId === row.segment.id}
                on:click={() => toggleSegment(row.segment.id)}
                role="button"
                tabindex="0"
                on:keydown={e => e.key === 'Enter' && toggleSegment(row.segment.id)}
              >
                <td class="px-4 py-2.5">
                  <div class="flex items-center gap-1.5">
                    {#if row.segment.sport}
                      <span>{sportIcon(row.segment.sport as any)}</span>
                    {/if}
                    <a href="{base}segments/{row.segment.id}/"
                       class="text-white hover:text-blue-400 transition-colors font-medium"
                       on:click|stopPropagation>
                      {row.segment.name}
                    </a>
                  </div>
                </td>
                <td class="px-4 py-2.5 text-zinc-400 hidden sm:table-cell">{formatDistance(row.segment.distance_m)}</td>
                <td class="px-4 py-2.5">
                  <a href="{base}activity/{row.best_activity_id}/"
                     class="font-mono text-white hover:text-blue-400 transition-colors"
                     on:click|stopPropagation
                     title="Activity where this PR was set">
                    {formatElapsed(row.best_elapsed_s)}
                  </a>
                </td>
                <td class="px-4 py-2.5 text-zinc-400 text-right pr-4">
                  <span class="inline-flex items-center gap-1.5">
                    {row.effort_count}
                    <span class="text-zinc-600 text-xs">{expandedId === row.segment.id ? '▲' : '▼'}</span>
                  </span>
                </td>
              </tr>

              <!-- Expanded effort list -->
              {#if expandedId === row.segment.id}
                <tr class="border-b border-zinc-800/50">
                  <td colspan="4" class="px-4 pb-3 pt-1">
                    {#if loadingEfforts[row.segment.id]}
                      <p class="text-zinc-500 text-xs py-2">Loading…</p>
                    {:else}
                      {@const efforts = effortsBySegment[row.segment.id] ?? []}
                      {@const pr = efforts.length ? Math.min(...efforts.map(e => e.elapsed_s)) : 0}
                      <div class="rounded-lg overflow-hidden border border-zinc-700/50">
                        <table class="w-full text-xs">
                          <tbody>
                            {#each efforts as e (e.activity_id + e.started_at)}
                              {@const delta = e.elapsed_s - pr}
                              {@const isPR = delta === 0}
                              <tr class="border-b border-zinc-700/30 last:border-0 hover:bg-zinc-700/20 transition-colors"
                                  class:bg-green-950={isPR}>
                                <td class="px-3 py-1.5">
                                  <a href="{base}activity/{e.activity_id}/"
                                     class="text-blue-400 hover:text-blue-300 transition-colors">
                                    {new Date(e.started_at).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })}
                                  </a>
                                </td>
                                <td class="px-3 py-1.5 font-mono text-white">{formatElapsed(e.elapsed_s)}</td>
                                <td class="px-3 py-1.5 font-medium"
                                    class:text-green-400={isPR}
                                    class:text-zinc-500={!isPR}>
                                  {#if isPR}PR{:else}+{delta < 60 ? `${delta}s` : `${Math.floor(delta/60)}m${(delta%60).toString().padStart(2,'0')}s`}{/if}
                                </td>
                              </tr>
                            {/each}
                          </tbody>
                        </table>
                      </div>
                    {/if}
                  </td>
                </tr>
              {/if}
            {/each}
          </tbody>
        </table>
      </div>
    {/if}

  <!-- Nerd Corner tab -->
  {:else if activeTab === 'nerd'}
    <div class="bg-zinc-900 rounded-xl p-4 border border-zinc-800">
      <h3 class="text-sm font-medium text-zinc-400 uppercase tracking-wide mb-4">Year over year</h3>
      <NerdCorner activities={allActivities} />
    </div>

  <!-- Explore tab -->
  {:else if activeTab === 'explore'}
    <div style="height: calc(100vh - 200px); margin: 0 -1rem -1.5rem;">
      <Explore {handle} {base} embedded={true} />
    </div>

  <!-- Profile tab -->
  {:else if activeTab === 'profile'}
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">

      <div class="bg-zinc-900 rounded-xl p-4 border border-zinc-800 space-y-3">
        <h3 class="text-sm font-medium text-zinc-400 uppercase tracking-wide">Key numbers</h3>
        {#if athlete.max_hr}
          <div class="flex justify-between text-sm">
            <span class="text-zinc-400">Max HR</span>
            <span class="text-white font-medium">{athlete.max_hr} bpm</span>
          </div>
        {/if}
        {#if athlete.ftp_w}
          <div class="flex justify-between text-sm">
            <span class="text-zinc-400">FTP</span>
            <span class="text-white font-medium">{athlete.ftp_w} W</span>
          </div>
        {/if}
        {#if !athlete.max_hr && !athlete.ftp_w}
          <p class="text-zinc-500 text-sm">Set <code>athlete.max_hr</code> and <code>athlete.ftp_w</code> in your config, or use Edit profile.</p>
        {/if}
      </div>

      {#if athlete.hr_zones}
        <div class="bg-zinc-900 rounded-xl p-4 border border-zinc-800 space-y-2">
          <h3 class="text-sm font-medium text-zinc-400 uppercase tracking-wide">HR Zones</h3>
          {#each athlete.hr_zones as _zone, i}
            <div class="flex justify-between items-center text-sm">
              <span class="text-zinc-400">Z{i + 1}</span>
              <span class="text-white">{fmtHrZone(athlete.hr_zones!, i)}</span>
            </div>
          {/each}
        </div>
      {/if}

      {#if athlete.power_zones}
        <div class="bg-zinc-900 rounded-xl p-4 border border-zinc-800 space-y-2">
          <h3 class="text-sm font-medium text-zinc-400 uppercase tracking-wide">Power Zones</h3>
          {#each athlete.power_zones as _zone, i}
            <div class="flex justify-between items-center text-sm">
              <span class="text-zinc-400">Z{i + 1}</span>
              <span class="text-white">{fmtZone(athlete.power_zones!, i)}</span>
            </div>
          {/each}
        </div>
      {/if}

    </div>
  {/if}

{/if}

{#if drawerOpen && editEnabled}
  <AthleteDrawer
    {editUrl}
    on:close={() => drawerOpen = false}
    on:saved={onSaved}
  />
{/if}
