<template>
  <div class="speedtest-card card-glow">
    <div class="card-header">
      <h2 class="card-title">Speedtest</h2>
      <button
        class="reload-btn"
        @click="runTests"
        :disabled="isTesting"
      >
        <IconifyIcon
          icon="mdi:reload"
          class="text-lg"
          :class="{ 'animate-spin': isTesting }"
        />
      </button>
    </div>

    <div class="metrics-grid">
      <div v-for="metric in metrics" :key="metric.label" class="metric-card">
        <div class="metric-header">
          <IconifyIcon :icon="metric.icon" class="text-lg text-m-accent" />
          <span class="font-mono text-[10px] font-medium uppercase tracking-[0.15em] text-m-muted">
            {{ metric.label }}
          </span>
        </div>
        <div class="metric-value-area">
          <template v-if="isTesting">
            <div class="h-10 w-16 animate-shimmer rounded" />
          </template>
          <template v-else>
            <span class="metric-value font-mono">
              {{ metric.value !== null ? metric.value : "--" }}
            </span>
          </template>
          <span class="metric-unit font-mono">{{ metric.unit }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {computed, ref} from "vue"
import {Icon as IconifyIcon} from "@iconify/vue"

const ping = ref<number | null>(null)
const download = ref<number | null>(null)
const upload = ref<number | null>(null)
const isTesting = ref(false)

const metrics = computed(() => [
  { label: "Download", icon: "mdi:arrow-down-bold", value: download.value, unit: "Mbps" },
  { label: "Upload", icon: "mdi:arrow-up-bold", value: upload.value, unit: "Mbps" },
  { label: "Ping", icon: "mdi:signal", value: ping.value, unit: "ms" },
])

async function testDownload() {
  const start = performance.now()
  const res = await fetch('/api/download')
  const blob = await res.blob()
  const end = performance.now()
  const size = blob.size
  const seconds = (end - start) / 1000
  download.value = Math.round((size * 8) / seconds / 1000000)
}

async function testUpload() {
  const size = 5 * 1024 * 1024
  const data = new Uint8Array(size)
  const start = performance.now()
  await fetch('/api/upload', { method: 'POST', body: data })
  const end = performance.now()
  const seconds = (end - start) / 1000
  upload.value = Math.round((size * 8) / seconds / 1000000)
}

async function testPing() {
  const start = performance.now()
  await fetch('/api/ping')
  const end = performance.now()
  ping.value = Math.round(end - start)
}

async function runTests() {
  isTesting.value = true
  download.value = null
  upload.value = null
  ping.value = null

  try {
    await testDownload()
    await testUpload()
    await testPing()
  } finally {
    isTesting.value = false
  }
}
</script>

<style scoped>
.speedtest-card {
  background: rgb(var(--m-secondary));
  border-radius: 12px;
  padding: 1.25rem;
  transition: background-color 0.4s ease;
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1rem;
}

.card-title {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  color: rgb(var(--m-text));
}

.reload-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgb(var(--m-tertiary));
  color: rgb(var(--m-accent));
  border: 1px solid rgb(var(--m-accent) / 0.12);
  cursor: pointer;
  transition: all 0.2s ease;
}

.reload-btn:hover:not(:disabled) {
  background: rgb(var(--m-accent) / 0.12);
  border-color: rgb(var(--m-accent) / 0.25);
}

.reload-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.metrics-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
}

.metric-card {
  background: rgb(var(--m-tertiary));
  border-radius: 10px;
  padding: 1rem;
  border: 1px solid rgb(var(--m-accent) / 0.06);
  transition: border-color 0.2s ease;
}

.metric-card:hover {
  border-color: rgb(var(--m-accent) / 0.15);
}

.metric-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.metric-value-area {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.125rem;
}

.metric-value {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1;
  color: rgb(var(--m-text));
}

.metric-unit {
  font-size: 0.65rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgb(var(--m-muted));
}
</style>
