<script lang="ts">
  import { downloads } from "$lib/stores/downloads";
  import { auth } from "$lib/stores/auth";
  import { commands } from "$lib/api/bindings";
  import type { MediaItem } from "$lib/api/types";

  interface Props {
    albumId: string;
    albumName: string;
    tracks: MediaItem[];
    className?: string;
  }

  let { albumId, albumName, tracks, className = "" }: Props = $props();

  let isProcessing = $state(false);

  // Calculate download status for all tracks in album
  const downloadStatuses = $derived(
    tracks.map((track) =>
      Object.values($downloads.downloads).find((d) => d.itemId === track.id)
    )
  );

  const completedCount = $derived(
    downloadStatuses.filter((d) => d?.status === "completed").length
  );

  const downloadingCount = $derived(
    downloadStatuses.filter(
      (d) => d?.status === "downloading" || d?.status === "pending"
    ).length
  );

  const failedCount = $derived(
    downloadStatuses.filter((d) => d?.status === "failed").length
  );

  const totalProgress = $derived(() => {
    if (tracks.length === 0) return 0;
    const activeDownloads = downloadStatuses.filter(
      (d) => d?.status === "downloading"
    );
    if (activeDownloads.length === 0) return completedCount / tracks.length;

    const downloadingProgress = activeDownloads.reduce(
      (sum, d) => sum + (d?.progress || 0),
      0
    );
    return (completedCount + downloadingProgress) / tracks.length;
  });

  const isFullyDownloaded = $derived(completedCount === tracks.length && tracks.length > 0);
  const isDownloading = $derived(downloadingCount > 0);
  const hasPartialDownload = $derived(completedCount > 0 && completedCount < tracks.length);

  async function handleClick() {
    if (isProcessing) return;

    isProcessing = true;
    try {
      const userId = $auth.user?.id;
      if (!userId) {
        console.error("No user ID found");
        return;
      }

      if (isFullyDownloaded) {
        // Delete all downloads for this album
        for (const status of downloadStatuses) {
          if (status?.id) {
            await downloads.delete(status.id);
          }
        }
      } else if (isDownloading) {
        // Cancel all active downloads for this album
        for (const status of downloadStatuses) {
          if (
            status?.id &&
            (status.status === "downloading" || status.status === "pending")
          ) {
            await downloads.cancel(status.id);
          }
        }
      } else {
        // Download the album: queue all tracks, then start each one
        const repo = auth.getRepository();
        const basePath = `albums/${albumId}`;
        const downloadIds = await downloads.downloadAlbum(albumId, userId, basePath);

        // Get target directory for downloads
        const targetDir = await commands.storageGetPath();

        // Enqueue each track with its resolved stream URL. The backend queue
        // pump starts up to max_concurrent at a time and advances through the
        // rest automatically as slots free up — so we never hit (and silently
        // drop) the concurrency limit the way startDownload did.
        for (let i = 0; i < tracks.length && i < downloadIds.length; i++) {
          try {
            const streamUrl = await repo.getAudioStreamUrl(tracks[i].id);
            if (streamUrl) {
              await commands.enqueueDownload(downloadIds[i], streamUrl, targetDir);
            }
          } catch (e) {
            console.error(`Failed to enqueue download for track ${tracks[i].id}:`, e);
          }
        }

        // Refresh to get updated statuses
        await downloads.refresh(userId);
      }
    } catch (error) {
      console.error("Album download operation failed:", error);
    } finally {
      isProcessing = false;
    }
  }

  function getTitle(): string {
    if (isFullyDownloaded) {
      return "Downloaded - Click to remove";
    }
    if (isDownloading) {
      return `Downloading ${completedCount + downloadingCount}/${tracks.length}... Click to cancel`;
    }
    if (hasPartialDownload) {
      return `${completedCount}/${tracks.length} downloaded - Click to download remaining`;
    }
    if (failedCount > 0) {
      return `${failedCount} failed - Click to retry`;
    }
    return "Download for offline playback";
  }

  function getStatusText(): string {
    if (isFullyDownloaded) return "";
    if (isDownloading || hasPartialDownload) {
      return `${completedCount}/${tracks.length}`;
    }
    return "";
  }
</script>

<button
  onclick={handleClick}
  disabled={isProcessing || tracks.length === 0}
  class="px-6 py-2 rounded-lg font-medium flex items-center gap-2 transition-colors {isFullyDownloaded
    ? 'bg-green-600 hover:bg-green-700 text-white'
    : isDownloading
      ? 'bg-blue-600 hover:bg-blue-700 text-white'
      : 'bg-[var(--color-surface)] hover:bg-[var(--color-surface-hover)]'} {isProcessing
    ? 'opacity-50 cursor-wait'
    : ''} {className}"
  title={getTitle()}
  aria-label={getTitle()}
>
  <div class="relative w-5 h-5">
    {#if isDownloading}
      <!-- Progress ring -->
      <svg class="absolute inset-0 -rotate-90" viewBox="0 0 24 24">
        <circle
          cx="12"
          cy="12"
          r="10"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          opacity="0.3"
        />
        <circle
          cx="12"
          cy="12"
          r="10"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-dasharray={2 * Math.PI * 10}
          stroke-dashoffset={2 * Math.PI * 10 * (1 - totalProgress())}
          stroke-linecap="round"
          class="transition-all duration-300"
        />
      </svg>
      <!-- Small download icon inside -->
      <svg
        class="absolute inset-0 m-auto w-3 h-3"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        stroke-width="2.5"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          d="M12 4v12m0 0l-4-4m4 4l4-4m-9 7h10"
        />
      </svg>
    {:else if isFullyDownloaded}
      <!-- Checkmark icon -->
      <svg
        class="w-5 h-5"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        stroke-width="2.5"
      >
        <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
      </svg>
    {:else if failedCount > 0}
      <!-- Error icon -->
      <svg
        class="w-5 h-5 text-red-400"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        stroke-width="2"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
        />
      </svg>
    {:else}
      <!-- Download icon -->
      <svg
        class="w-5 h-5"
        fill="none"
        stroke="currentColor"
        viewBox="0 0 24 24"
        stroke-width="2"
      >
        <path
          stroke-linecap="round"
          stroke-linejoin="round"
          d="M12 4v12m0 0l-4-4m4 4l4-4m-9 7h10"
        />
      </svg>
    {/if}
  </div>

  {#if isDownloading || hasPartialDownload}
    <span>{getStatusText()}</span>
  {:else if isFullyDownloaded}
    <span>Downloaded</span>
  {:else}
    <span>Download</span>
  {/if}
</button>
