<script lang="ts">
  /**
   * Core download button UI component - Renders download state with progress
   * Used as base for all download button variants (tracks, albums, videos, series)
   *
   * @req: UR-011 - Download for offline playback
   * @req: UR-018 - Download entire albums or playlists
   * @req: DR-018 - Download buttons on library/album/player screens
   */

  export interface DownloadState {
    status: "not_downloaded" | "downloading" | "pending" | "completed" | "failed";
    progress: number; // 0-1
  }

  interface Props {
    state: DownloadState;
    size?: "sm" | "md" | "lg";
    title: string;
    onClick?: () => void | Promise<void>;
    isProcessing?: boolean;
    className?: string;
  }

  let { state, size = "md", title, onClick, isProcessing = false, className = "" }: Props = $props();

  const sizeMap = {
    sm: { icon: "w-4 h-4", ring: "w-8 h-8" },
    md: { icon: "w-5 h-5", ring: "w-10 h-10" },
    lg: { icon: "w-6 h-6", ring: "w-12 h-12" },
  };

  const colorMap = {
    not_downloaded: "text-gray-400 hover:text-white",
    downloading: "text-blue-500",
    pending: "text-yellow-500",
    completed: "text-green-500",
    failed: "text-red-500",
  };

  const circumference = 2 * Math.PI * 15;
  const offset = $derived(circumference - (state.progress || 0) * circumference);
</script>

<button
  onclick={onClick}
  disabled={isProcessing || state.status === "downloading"}
  aria-label={title}
  title={title}
  class={`relative transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${colorMap[state.status]} ${className}`}
>
  {#if state.status === "downloading"}
    <!-- Progress Ring -->
    <svg class="{sizeMap[size].ring} -rotate-90" viewBox="0 0 36 36">
      <circle cx="18" cy="18" r="15" fill="none" stroke="currentColor" stroke-width="2" class="opacity-20" />
      <circle
        cx="18"
        cy="18"
        r="15"
        fill="none"
        stroke="currentColor"
        stroke-width="2"
        stroke-dasharray={circumference}
        stroke-dashoffset={offset}
        stroke-linecap="round"
        class="transition-all"
        style="transition: stroke-dashoffset 0.3s ease;"
      />
      <!-- Download percentage in Center (counter-rotate to cancel SVG's -rotate-90) -->
      <text x="18" y="20" text-anchor="middle" transform="rotate(90, 18, 18)" class="text-xs font-bold fill-current">
        {Math.round(state.progress * 100)}%
      </text>
    </svg>
  {:else if state.status === "completed"}
    <!-- Checkmark Icon -->
    <svg class={sizeMap[size].icon} fill="currentColor" viewBox="0 0 24 24">
      <path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z" />
    </svg>
  {:else if state.status === "failed"}
    <!-- Error Icon -->
    <svg class={sizeMap[size].icon} fill="currentColor" viewBox="0 0 24 24">
      <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z" />
    </svg>
  {:else if state.status === "pending"}
    <!-- Pending Icon (clock) -->
    <svg class={sizeMap[size].icon} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <circle cx="12" cy="12" r="9" stroke-width="2" />
      <path stroke-width="2" stroke-linecap="round" d="M12 6v6l4 2" />
    </svg>
  {:else}
    <!-- Download Icon -->
    <svg class={sizeMap[size].icon} fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
    </svg>
  {/if}
</button>
