<template>
  <v-card
    border
    class="my-6"
    rounded
    style="border-radius: 10px; border: 2px solid grey"
    variant="elevated">
    <v-card-title class="d-flex align-center justify-space-between w-100">
      <span v-if="packageCount.building > 0" class="d-flex">
        <div class="pulsating-circle-amber me-4" style="transform: translateY(10px)" />
        <span>Building</span>
      </span>
      <span v-else class="d-flex">
        <div class="pulsating-circle-green me-4" style="transform: translateY(10px)" />
        <span>Idle</span>
      </span>
      <v-sheet class="d-flex align-center w-100">
        <v-progress-linear
          :max="packageCount.built + packageCount.building + packageCount.queued"
          :model-value="packageCount.built"
          color="light-blue"
          height="10"
          rounded
          striped
          style="transform: translateX(-620px)"></v-progress-linear>
        <span
          class="text-grey me-2"
          style="font-size: 13px; min-width: 220px; width: 220px; padding-left: 60px">
          Last updated
          {{
            lastUpdatedSeconds > 59
              ? rtf.format(-Math.floor(lastUpdatedSeconds / 60), 'minutes')
              : rtf.format(-lastUpdatedSeconds, 'seconds')
          }}
        </span>
      </v-sheet>
    </v-card-title>

    <v-card-text v-if="packageCount.building > 0 || packageCount.queued > 0" class="d-flex">
      <v-list width="50%">
        <v-list-subheader>Building</v-list-subheader>
        <v-list-item v-for="(pkg, index) in packages.building" :key="index">
          <template v-slot:prepend>
            <div class="pulsating-circle-amber me-4" />
          </template>
          <v-list-item-title>
            {{ pkg.pkgbase }} <span class="text-grey">({{ pkg.repo }})</span>
          </v-list-item-title>
          <v-list-item-subtitle>{{ pkg.arch_version }}</v-list-item-subtitle>
        </v-list-item>
      </v-list>

      <v-list width="50%">
        <v-list-subheader>Queued</v-list-subheader>
        <v-list-item
          v-for="(pkg, index) in packages.queued.slice(0, packageCount.building)"
          :key="index"
          prepend-icon="mdi-chevron-right">
          <v-list-item-title>
            {{ pkg.pkgbase }} <span class="text-grey">({{ pkg.repo }})</span>
          </v-list-item-title>
          <v-list-item-subtitle>{{ pkg.arch_version }}</v-list-item-subtitle>
        </v-list-item>
        <v-list-item
          v-if="packageCount.queued > packageCount.building"
          prepend-icon="mdi-dots-horizontal">
          <v-list-item-title>
            <span v-if="packageCount.building > 0">+</span>
            {{ packageCount.queued - packageCount.building }}
            <span v-if="packageCount.building > 0">more</span><span v-else>in queue</span>
          </v-list-item-title>
        </v-list-item>
      </v-list>
    </v-card-text>
  </v-card>
</template>

<script lang="ts" setup>
// built + building + queued = total
import { onMounted, ref } from 'vue'
import type { Packages } from '@/types/Packages'
import { Package } from '@/types/Package'

// This variable sets the update-interval
const updateIntervalInMinutes = 5

const lastUpdatedTime = ref(0)
const lastUpdatedSeconds = ref(0)
const rtf = new Intl.RelativeTimeFormat('en', {
  localeMatcher: 'best fit',
  numeric: 'always',
  style: 'long'
})

const packageCount = ref({
  total: 0,
  building: 0,
  built: 0,
  queued: 0
})
const packages = ref<{
  built: Array<Package>
  building: Array<Package>
  queued: Array<Package>
}>({
  built: [],
  building: [],
  queued: []
})

const getTotalPackages = () => {
  fetch('https://api.alhp.dev/packages?limit=1&offset=0', {
    method: 'GET'
  })
    .then((response) => {
      if (response.ok) return response.json()
    })
    .then((json: Packages) => {
      if (!json) return
      packageCount.value.total = json.total
    })
    .catch((error) => {
      console.error(error)
    })
}

const getBuiltPackages = () => {
  fetch('https://api.alhp.dev/packages?limit=0&offset=0&status=build', {
    method: 'GET'
  })
    .then((response) => {
      if (response.ok) return response.json()
    })
    .then((json: Packages) => {
      if (!json) return
      packageCount.value.built = json.total
      packages.value.built = json.packages
    })
    .catch((error) => {
      console.error(error)
    })
}

const getBuildingPackages = () => {
  fetch('https://api.alhp.dev/packages?limit=0&offset=0&status=building', {
    method: 'GET'
  })
    .then((response) => {
      if (response.ok) return response.json()
    })
    .then((json: Packages) => {
      if (!json) return
      packageCount.value.building = json.total
      packages.value.building = json.packages
    })
    .catch((error) => {
      console.error(error)
    })
}

const getQueuedPackages = () => {
  fetch('https://api.alhp.dev/packages?limit=0&offset=0&status=queued', {
    method: 'GET'
  })
    .then((response) => {
      if (response.ok) return response.json()
    })
    .then((json: Packages) => {
      if (!json) return
      packageCount.value.queued = json.total
      packages.value.queued = json.packages
    })
    .catch((error) => {
      console.error(error)
    })
}

onMounted(() => {
  getTotalPackages()
  getBuiltPackages()
  getBuildingPackages()
  getQueuedPackages()
  lastUpdatedTime.value = Date.now()
  lastUpdatedSeconds.value = Math.floor((Date.now() - lastUpdatedTime.value) / 1000)

  const lastUpdatedInterval = setInterval(() => {
    lastUpdatedSeconds.value = Math.floor((Date.now() - lastUpdatedTime.value) / 1000)
  }, 1000)

  const interval = setInterval(
    () => {
      getTotalPackages()
      getBuiltPackages()
      getBuildingPackages()
      getQueuedPackages()
      lastUpdatedTime.value = Date.now()
      lastUpdatedSeconds.value = Math.floor((Date.now() - lastUpdatedTime.value) / 1000)
    },
    updateIntervalInMinutes * 60 * 1000
  )
})
</script>

<style lang="scss">
.pulsating-circle-green {
  background-color: rgba(126, 206, 5, 0.94);
  border-radius: 50%;
  width: 12px;
  height: 12px;
}

.pulsating-circle-green:before {
  content: '';
  display: block;
  width: 200%;
  height: 200%;
  box-sizing: border-box;
  margin-left: -50%;
  margin-top: -50%;
  border-radius: 50%;
  background-color: rgba(126, 206, 5, 0.94);
  -webkit-animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
  animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

.pulsating-circle-amber {
  background-color: #f39c12f0;
  border-radius: 50%;
  width: 12px;
  height: 12px;
}

.pulsating-circle-amber:before {
  content: '';
  display: block;
  width: 200%;
  height: 200%;
  box-sizing: border-box;
  margin-left: -50%;
  margin-top: -50%;
  border-radius: 50%;
  background-color: #f39c12;
  -webkit-animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
  animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

@-webkit-keyframes pulse-ring {
  0% {
    transform: scale(0.33);
  }
  80%,
  100% {
    opacity: 0;
  }
}

@keyframes pulse-ring {
  0% {
    transform: scale(0.33);
  }
  80%,
  100% {
    opacity: 0;
  }
}

@-webkit-keyframes pulse-dot {
  0% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}

@keyframes pulse-dot {
  0% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}
</style>
