<script lang="ts">
  import { onMount, onDestroy } from "svelte";
  import { invoke } from "@tauri-apps/api/core";
  import { listen } from "@tauri-apps/api/event";
  import { errorMessage } from "$lib/utils/errors.js";
  import Card from "$lib/components/Card.svelte";

  let { modelSize = "base", onComplete = () => {} } = $props<{
    modelSize?: "tiny" | "base" | "small" | "medium";
    onComplete?: () => void;
  }>();

  let progress = $state(0);
  let downloading = $state(false);
  let downloaded = $state(0);
  let total = $state(0);
  let error = $state("");
  let unlisten: null | (() => void) = null;

  const modelInfo = {
    tiny: { size: "~75 MB", accuracy: "Basic" },
    base: { size: "~142 MB", accuracy: "Good" },
    small: { size: "~466 MB", accuracy: "Better" },
    medium: { size: "~1.5 GB", accuracy: "Best" },
  } satisfies Record<string, { size: string; accuracy: string }>;
  let currentModelInfo = $derived(
    modelInfo[String(modelSize) as keyof typeof modelInfo]
  );

  onMount(async () => {
    unlisten = await listen("model-download-progress", (event) => {
      const data = event.payload as { progress?: number; downloaded?: number; total?: number };
      progress = data.progress ?? 0;
      downloaded = data.downloaded ?? 0;
      total = data.total ?? 0;
    });
  });

  onDestroy(() => {
    if (unlisten) unlisten();
  });

  async function startDownload() {
    downloading = true;
    error = "";
    progress = 0;
    try {
      await invoke("download_model", { size: modelSize });
      onComplete();
    } catch (err) {
      error = errorMessage(err) || "Download failed";
      downloading = false;
    }
  }

  function formatBytes(bytes: number) {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
    if (bytes < 1073741824) return `${(bytes / 1048576).toFixed(1)} MB`;
    return `${(bytes / 1073741824).toFixed(2)} GB`;
  }
</script>

<div class="flex flex-col items-center justify-center h-full px-8 animate-fade-in">
  <Card classes="max-w-md w-full" elevation="raised">
    <div class="p-8 text-center">
      <div class="w-16 h-16 rounded-full bg-accent/10 flex items-center justify-center mx-auto mb-5">
        <svg class="w-8 h-8 text-accent" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" />
        </svg>
      </div>

      <h3 class="text-[18px] font-semibold text-text mb-2">Download Whisper Model</h3>
      <p class="text-[13px] text-text-secondary mb-1">
        Lumotia needs the <span class="font-medium text-text">{modelSize}</span> model to transcribe speech.
      </p>
      <p class="text-[12px] text-text-secondary mb-6">
        {currentModelInfo?.size ?? "?"} · {currentModelInfo?.accuracy ?? "?"} accuracy · 100% offline
      </p>

      {#if downloading}
        <div class="mb-4">
          <div class="h-[6px] bg-bg-elevated rounded-full overflow-hidden mb-2">
            <div
              class="h-full bg-accent rounded-full transition-all duration-300 shadow-[var(--shadow-accent-glow)]"
              style="width: {progress}%"
            ></div>
          </div>
          <p class="text-[12px] text-text-secondary">
            {progress}% · {formatBytes(downloaded)} / {formatBytes(total)}
          </p>
        </div>
      {:else}
        <button
          class="px-6 py-2.5 rounded-xl text-[14px] font-medium text-white bg-accent hover:bg-accent-hover
                 shadow-[var(--shadow-accent-md)] transition-all duration-150"
          onclick={startDownload}
        >
          Download Model
        </button>
      {/if}

      {#if error}
        <p class="text-[12px] text-danger mt-3">{error}</p>
      {/if}

      <p class="text-[12px] text-text-secondary mt-5">
        Models are cached locally. No data leaves your machine.
      </p>
    </div>
  </Card>
</div>
