<template>
  <v-snackbar
    v-for="(info, i) in infos"
    :key="info.Id || i"
    :model-value="true"
    :timeout="-1"
    color="transparent"
    location="bottom end"
    rounded="lg"
    class="bg-transparent"
    min-width="240"
    elevation="0"
    variant="elevated"
    :style="{ 'margin-bottom': calcMargin(i) }"
  >
    <v-alert
      :model-value="true"
      :color="`#303474`"
      prominent
      rounded="lg"
      width="380"
      icon="download"
    >
      <v-btn
        icon
        variant="text"
        class="position-absolute"
        style="top: 6px; right: 6px"
        data-test="download-close"
        @click="onClose(info, i)"
      >
        <v-icon>close</v-icon>
      </v-btn>

      Downloading
      <span v-if="info.IsDecryption">&nbsp;and decrypting&nbsp;</span>
      <div
        v-if="info.Title"
        class="font-weight-bold"
        >{{ info.Title }}</div
      >

      <v-progress-linear
        v-if="info.StatusText !== undefined"
        v-model="info.Percentage"
        :color="
          info.StatusText === 'Download Cancelled' ? '#9e9e9e' : '#2596be'
        "
        height="25"
      >
        <strong>{{ info.StatusText }}</strong>
      </v-progress-linear>

      <v-progress-linear
        v-else-if="info.Total !== 0"
        v-model="info.Percentage"
        :color="
          info.StatusText === 'Download Cancelled' ? '#9e9e9e' : '#2596be'
        "
        height="25"
      >
        <strong
          >{{ toFormattedBytes(info?.Completed ?? 0) }} /
          {{ toFormattedBytes(info?.Total ?? 0) }}</strong
        >
      </v-progress-linear>

      <div class="mt-3 flex justify-end gap-2">
        <v-tooltip :text="info.StatusText === 'Paused' ? 'Resume' : 'Pause'">
          <template #activator="{ props }">
            <v-btn
              v-bind="props"
              icon
              variant="text"
              data-test="download-pause-toggle"
              @click="onTogglePause(info)"
            >
              <v-icon>{{
                info.StatusText === 'Paused' ? 'play_arrow' : 'pause'
              }}</v-icon>
            </v-btn>
          </template>
        </v-tooltip>

        <v-btn
          size="small"
          variant="text"
          data-test="download-cancel"
          @click="onCancel(info)"
          >Cancel</v-btn
        >
      </div>
    </v-alert>
  </v-snackbar>
</template>

<script setup lang="ts">
import { storeToRefs } from 'pinia';
import { useDownloadStore } from '@/stores/download.store';

type DownloadInfo = {
  Id?: string;
  id?: string;
  Title?: string;
  StatusText?: string;
  Completed?: number;
  Total?: number;
  IsDecryption?: boolean;
  Percentage?: number;
};

const store = useDownloadStore();
const { infos } = storeToRefs(store);

function calcMargin(i: number): string {
  return i * 90 + 20 + 'px';
}

function onTogglePause(info: DownloadInfo): void {
  const id = info.Id ?? info.id;
  if (!id) return;
  if (info.StatusText === 'Paused') store.requestResume(id);
  else store.requestPause(id);
}

function onCancel(info: DownloadInfo): void {
  const id = info.Id ?? info.id;
  if (!id) return;
  store.requestCancel(id);
}

function onClose(info: DownloadInfo, index: number): void {
  const id = info.Id ?? info.id;
  if (id) {
    const idx = infos.value.findIndex((x) => x.Id === id);
    if (idx >= 0) infos.value.splice(idx, 1);
  } else {
    if (index >= 0 && index < infos.value.length) infos.value.splice(index, 1);
  }
}

function toFormattedBytes(n: number) {
  if (!Number.isFinite(n)) return '0 B';
  const units = ['B', 'KB', 'MB', 'GB', 'TB'];
  let i = 0,
    v = Math.max(n, 0);
  while (v >= 1024 && i < units.length - 1) {
    v /= 1024;
    i++;
  }
  return `${v.toFixed(v < 10 && i > 0 ? 1 : 0)} ${units[i]}`;
}
</script>
