<script lang="ts">
  import { Disc3, Album, Music2, X } from 'lucide-svelte';
  import { useQueryClient } from '@tanstack/svelte-query';
  import { createMyRequestsQuery, cancelRequest } from '$lib/api/requests';
  import { qk } from '$lib/api/queries';
  import StatusPill from '$lib/components/StatusPill.svelte';
  import ApiErrorBanner from '$lib/components/ApiErrorBanner.svelte';
  import DiscoverTabs from '$lib/components/DiscoverTabs.svelte';
  import type { LidarrRequest, LidarrRequestKind } from '$lib/api/types';

  const queryStore = createMyRequestsQuery();
  const query = $derived($queryStore);
  const requests = $derived((query.data ?? []) as LidarrRequest[]);

  const client = useQueryClient();

  async function onCancel(id: string) {
    try {
      await cancelRequest(id);
      await client.invalidateQueries({ queryKey: qk.myRequests() });
    } catch {
      // Swallow for v1; toast surface lands later. The row stays put so the
      // user can retry — failed cancel doesn't lie about success.
    }
  }

  function fallbackIcon(kind: LidarrRequestKind) {
    if (kind === 'artist') return Disc3;
    if (kind === 'album') return Album;
    return Music2;
  }

  function rowTitle(r: LidarrRequest): string {
    if (r.kind === 'artist') return r.artist_name;
    if (r.kind === 'album')  return r.album_title ?? '—';
    return r.track_title ?? '—';
  }

  // Used in aria-labels — '—' is meaningless to screen readers, so when a
  // title is missing fall back to a generic-but-intelligible phrase.
  function rowAccessibleName(r: LidarrRequest): string {
    if (r.kind === 'artist') return r.artist_name;
    if (r.kind === 'album')  return r.album_title  ?? `this album by ${r.artist_name}`;
    return r.track_title ?? `this track by ${r.artist_name}`;
  }

  // Keep the meta line short and readable. We always lead with the artist,
  // then a relative-ish date — locale formatting is good enough for v1
  // and keeps tests deterministic without pinning Intl.RelativeTimeFormat.
  function rowMeta(r: LidarrRequest): string {
    const when = new Date(r.requested_at).toLocaleDateString();
    if (r.kind === 'artist') return `Requested ${when}`;
    return `by ${r.artist_name} · ${when}`;
  }

  function listenHref(r: LidarrRequest): string | null {
    if (r.matched_track_id)  return `/tracks/${r.matched_track_id}`;
    if (r.matched_album_id)  return `/albums/${r.matched_album_id}`;
    if (r.matched_artist_id) return `/artists/${r.matched_artist_id}`;
    return null;
  }
</script>

<DiscoverTabs />

<div class="space-y-6 pt-6">
  <header class="space-y-1">
    <h2 class="font-display text-2xl font-medium text-text-primary">
      Your requests
    </h2>
    <p class="text-text-secondary">
      What you've asked Minstrel to add to the library.
    </p>
  </header>

  {#if query.isError}
    <ApiErrorBanner error={query.error} onRetry={query.refetch} />
  {:else if query.isPending}
    <p class="text-text-secondary">Reading the ledger…</p>
  {:else if requests.length === 0}
    <p class="text-text-secondary">Nothing requested yet.</p>
  {:else}
    <ul class="divide-y divide-border rounded-lg border border-border bg-surface">
      {#each requests as r (r.id)}
        {@const Icon = fallbackIcon(r.kind)}
        {@const href = listenHref(r)}
        <li class="flex items-center gap-4 p-3" data-testid="request-row" data-status={r.status}>
          <div
            class="flex h-14 w-14 shrink-0 items-center justify-center rounded-md bg-surface-hover"
            aria-hidden="true"
          >
            <Icon size={24} strokeWidth={1} class="text-text-muted" />
          </div>

          <div class="min-w-0 flex-1 space-y-1">
            <div class="flex flex-wrap items-center gap-2">
              <span class="kind-pill">{r.kind}</span>
              <StatusPill status={r.status} />
            </div>
            <div class="truncate text-base font-medium text-text-primary">
              {rowTitle(r)}
            </div>
            <div class="truncate text-sm text-text-secondary">
              {rowMeta(r)}
            </div>
            {#if r.status === 'rejected' && r.notes}
              <div class="text-sm text-text-secondary" data-testid="rejection-notes">
                {r.notes}
              </div>
            {/if}
          </div>

          <div class="flex shrink-0 items-center gap-2">
            {#if r.status === 'pending'}
              <button
                type="button"
                aria-label={`Cancel request for ${rowAccessibleName(r)}`}
                class="inline-flex items-center gap-1 rounded-md border border-border px-3 py-1.5 text-sm text-text-secondary hover:bg-surface-hover"
                onclick={() => onCancel(r.id)}
              >
                <X size={16} strokeWidth={1} /> Cancel
              </button>
            {:else if r.status === 'completed' && href}
              <a
                {href}
                aria-label={`Listen to ${rowAccessibleName(r)}`}
                class="inline-flex items-center gap-1 text-sm text-accent hover:underline"
              >
                <Music2 size={16} strokeWidth={1} /> Listen
              </a>
            {/if}
          </div>
        </li>
      {/each}
    </ul>
  {/if}
</div>

<style>
  .kind-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    line-height: 14px;
    background: color-mix(in srgb, var(--fs-accent) 15%, transparent);
    color: var(--fs-accent);
    text-transform: capitalize;
  }
</style>
