<script lang="ts">
  import {
    AlertCircle,
    Download,
    LoaderCircle,
    PackageCheck,
    Sparkles,
    X,
  } from "@lucide/svelte";

  type UpdateToastState = "available" | "downloading" | "installed" | "error";

  interface Props {
    state: UpdateToastState;
    version: string;
    currentVersion: string;
    progress: number;
    error: string;
    onInstall: () => void;
    onLater: () => void;
    onDismiss: () => void;
  }

  let {
    state,
    version,
    currentVersion = "",
    progress = 0,
    error = "",
    onInstall,
    onLater,
    onDismiss,
  }: Props = $props();

  const clampedProgress = $derived(Math.max(0, Math.min(100, Math.round(progress))));
  const title = $derived(
    state === "installed"
      ? "Update installed"
      : state === "downloading"
        ? "Installing update"
        : state === "error"
          ? "Update failed"
          : "Update available",
  );
  const description = $derived(
    state === "installed"
      ? "Restart Gitty to use the new version."
      : state === "downloading"
        ? "Download and installation are running in the background."
        : state === "error"
          ? (error || "The update could not be installed.")
          : "Do you want to install this version now?",
  );
  const versionLabel = $derived(
    version && currentVersion
      ? `${currentVersion} → ${version}`
      : version
        ? `Version ${version}`
        : "New version",
  );
  const showProgress = $derived(state === "downloading" || state === "installed");
  const isBusy = $derived(state === "downloading");
</script>

<section
  class="update-toast"
  class:error={state === "error"}
  class:installed={state === "installed"}
  role={state === "error" ? "alert" : "status"}
  aria-live={state === "error" ? "assertive" : "polite"}
>
  <header class="update-toast-header">
    <div class="update-toast-icon" class:busy={isBusy}>
      {#if state === "downloading"}
        <LoaderCircle class="spin" size={18} aria-hidden="true" />
      {:else if state === "installed"}
        <PackageCheck size={18} aria-hidden="true" />
      {:else if state === "error"}
        <AlertCircle size={18} aria-hidden="true" />
      {:else}
        <Sparkles size={18} aria-hidden="true" />
      {/if}
    </div>

    <div class="update-toast-copy">
      <span class="update-toast-kicker">Gitty update · {versionLabel}</span>
      <h2>{title}</h2>
    </div>

    {#if !isBusy}
      <button class="update-toast-close" type="button" onclick={onDismiss} title="Close" aria-label="Close">
        <X size={15} aria-hidden="true" />
      </button>
    {/if}
  </header>

  <div class="update-toast-body">
    <p>{description}</p>

    {#if showProgress}
      <div
        class="update-progress"
        class:indeterminate={state === "downloading" && clampedProgress === 0}
        role="progressbar"
        aria-valuemin="0"
        aria-valuemax="100"
        aria-valuenow={clampedProgress}
      >
        <span style={`width: ${clampedProgress}%`}></span>
      </div>
      <div class="update-progress-label">
        {state === "installed" ? "100% complete" : clampedProgress > 0 ? `${clampedProgress}%` : "Waiting for download size"}
      </div>
    {/if}

  </div>

  <footer class="update-toast-actions">
    {#if state === "installed"}
      <button class="update-toast-secondary" type="button" onclick={onDismiss}>
        Got it
      </button>
    {:else if state === "error"}
      <button class="update-toast-secondary" type="button" onclick={onDismiss}>
        Close
      </button>
      <button class="update-toast-primary" type="button" onclick={onInstall}>
        <Download size={14} aria-hidden="true" />
        Try again
      </button>
    {:else}
      <button class="update-toast-secondary" type="button" onclick={onLater} disabled={isBusy}>
        Later
      </button>
      <button class="update-toast-primary" type="button" onclick={onInstall} disabled={isBusy}>
        {#if isBusy}
          <LoaderCircle class="spin" size={14} aria-hidden="true" />
          Installing
        {:else}
          <Download size={14} aria-hidden="true" />
          Install
        {/if}
      </button>
    {/if}
  </footer>
</section>
