<script lang="ts">
  import { downloads, videoDownloads } from "$lib/stores/downloads";
  import { auth } from "$lib/stores/auth";
  import { commands } from "$lib/api/bindings";
  import { QUALITY_PRESETS, type QualityPreset } from "$lib/api/quality-presets";
  import { createLogger } from "$lib/utils/logger";

  const log = createLogger("SeriesDownloadButton");

  interface Props {
    seriesId: string;
    seriesName: string;
    episodeCount?: number;
    className?: string;
  }

  let { seriesId, seriesName, episodeCount, className = "" }: Props = $props();

  let isProcessing = $state(false);
  let showQualityPicker = $state(false);

  // Count downloads for this series
  const seriesDownloads = $derived($videoDownloads.filter((d) => d.seriesName === seriesName));

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

  const inProgressCount = $derived(
    seriesDownloads.filter((d) => d.status === "downloading" || d.status === "pending").length,
  );

  const hasDownloads = $derived(completedCount > 0 || inProgressCount > 0);
  const allDownloaded = $derived(episodeCount !== undefined && completedCount >= episodeCount);

  async function startSeriesDownload(quality: QualityPreset) {
    showQualityPicker = false;
    if (isProcessing) return;

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

      log.debug("📺 Starting series download for:", seriesName, "quality:", quality);

      // Get target directory
      const targetDir = await commands.storageGetPath();
      const basePath = `${targetDir}/videos`;

      // Queue all episodes
      const downloadIds = await downloads.downloadSeries(
        seriesId,
        seriesName,
        userId,
        basePath,
        quality,
      );

      log.debug(`   Queued ${downloadIds.length} episodes for download`);

      // Pin the series item
      await downloads.pinItem(seriesId);

      // Resolve each episode's transcode URL (server-side) and enqueue. The
      // backend pump then starts up to max_concurrent and advances through the
      // rest as slots free up.
      const handle = auth.getRepository().getHandle();
      await commands.enqueueVideoDownloads(handle, downloadIds, targetDir);
      log.debug("   Episodes enqueued; backend pump will start them");
    } catch (error) {
      log.error("Failed to start series download:", error);
    } finally {
      isProcessing = false;
    }
  }

  function handleClick() {
    if (isProcessing) return;
    showQualityPicker = true;
  }

  function getButtonText(): string {
    if (allDownloaded) {
      return "Downloaded";
    }
    if (inProgressCount > 0) {
      return `Downloading... (${inProgressCount})`;
    }
    if (completedCount > 0 && episodeCount) {
      return `Download (${completedCount}/${episodeCount})`;
    }
    return "Download Series";
  }

  function getButtonColor(): string {
    if (allDownloaded) {
      return "bg-green-600 hover:bg-green-700";
    }
    if (inProgressCount > 0) {
      return "bg-blue-600 hover:bg-blue-700";
    }
    return "bg-[var(--color-jellyfin)] hover:bg-[var(--color-jellyfin-hover)]";
  }
</script>

<div class="relative {className}">
  <button
    onclick={handleClick}
    disabled={isProcessing || allDownloaded}
    class="flex items-center gap-2 px-4 py-2 rounded-lg text-white font-medium transition-colors {getButtonColor()} {isProcessing ||
    allDownloaded
      ? 'opacity-70 cursor-not-allowed'
      : ''}"
  >
    {#if inProgressCount > 0}
      <!-- Spinner -->
      <svg class="w-5 h-5 animate-spin" fill="none" viewBox="0 0 24 24">
        <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"
        ></circle>
        <path
          class="opacity-75"
          fill="currentColor"
          d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
        ></path>
      </svg>
    {:else if allDownloaded}
      <!-- Checkmark -->
      <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="M5 13l4 4L19 7" />
      </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}
    <span>{getButtonText()}</span>
  </button>

  <!-- Quality picker dropdown -->
  {#if showQualityPicker}
    <div
      class="absolute z-50 mt-2 left-0 w-48 bg-[var(--color-surface)] rounded-lg shadow-xl border border-gray-700 overflow-hidden"
    >
      <div class="p-3 border-b border-gray-700">
        <div class="text-sm font-medium text-white">Download Quality</div>
        {#if episodeCount}
          <div class="text-xs text-gray-400 mt-1">{episodeCount} episodes</div>
        {/if}
      </div>
      {#each Object.entries(QUALITY_PRESETS) as [key, preset]}
        <button
          onclick={() => startSeriesDownload(key as QualityPreset)}
          class="w-full px-4 py-3 text-left hover:bg-gray-700 transition-colors flex justify-between items-center"
        >
          <span class="text-sm text-white">{preset.label}</span>
          {#if preset.videoBitrate}
            <span class="text-xs text-gray-500"
              >{Math.round(preset.videoBitrate / 1_000_000)}Mbps</span
            >
          {:else}
            <span class="text-xs text-gray-500">Direct</span>
          {/if}
        </button>
      {/each}
      <button
        onclick={() => (showQualityPicker = false)}
        class="w-full px-4 py-3 text-left text-sm text-gray-400 hover:bg-gray-700 border-t border-gray-700"
      >
        Cancel
      </button>
    </div>
  {/if}
</div>

<!-- Click outside to close -->
{#if showQualityPicker}
  <button
    class="fixed inset-0 z-40"
    onclick={() => (showQualityPicker = false)}
    aria-label="Close quality picker"
  ></button>
{/if}
