<template>
  <v-card
    border
    class="my-6"
    rounded
    style="border-radius: 10px; border: 2px solid grey"
    variant="elevated">
    <v-card-title>
      <v-row align="center" class="w-100" style="margin-top: 1px">
        <v-col class="v-col-12 v-col-lg-1 mb-3">
          <v-row :class="mobile ? 'mt-1' : ''" class="flex-nowrap ms-1 d-flex align-items-center">
            <div
              :class="
                updateFailed
                  ? 'pulsating-circle-error'
                  : packageArrays.building.length > 0
                    ? 'pulsating-circle-amber'
                    : 'pulsating-circle-green'
              "
              class="circle-offset flex-circle" />
            <span class="ms-2">
              {{
                updateFailed
                  ? 'Could not fetch data.'
                  : packageArrays.building.length > 0
                    ? 'Building'
                    : 'Idle'
              }}
            </span>
          </v-row>
        </v-col>
        <v-col v-if="packageArrays.building.length > 0" class="v-col-12 v-col-lg-8 mb-3">
          <v-progress-linear
            :max="
              packageArrays.built.length +
              packageArrays.building.length +
              packageArrays.queued.length
            "
            :model-value="packageArrays.built.length"
            color="light-blue"
            height="10"
            rounded
            striped></v-progress-linear>
        </v-col>
        <v-col
          :class="mobile ? 'mt-n3' : 'text-end ms-auto'"
          class="text-grey v-col-12 v-col-lg-2 mb-3"
          cols="auto"
          style="font-size: 13px">
          <div v-if="!updateFailed" class="d-flex flex-column">
            <span>
              Last updated
              {{ formatTimeAgo(lastUpdatedSeconds) }}
            </span>
            <span>
              Last Mirror sync
              {{ formatTimeAgo(lastMirrorSync) }}
            </span>
          </div>

          <template v-else>Please try again later.</template>
        </v-col>
      </v-row>
    </v-card-title>
    <v-card-text
      v-if="packageArrays.building.length > 0 || packageArrays.queued.length > 0"
      class="d-flex flex-column">
      <v-list v-if="packageArrays.building.length > 0" class="mb-4" width="100%">
        <v-list-subheader>Building</v-list-subheader>
        <v-list-item v-for="(pkg, index) in packageArrays.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-sheet class="ps-4" color="transparent" rounded width="100%">
        <h4 class="mb-2 font-weight-light text-grey">Queued</h4>
        <queued-packages-list :packages="packageArrays.queued" />
      </v-sheet>
    </v-card-text>
  </v-card>
</template>

<script lang="ts" setup>
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue'
import { useDisplay } from 'vuetify'
import QueuedPackagesList from '@/components/CurrentlyBuilding/QueuedPackagesList.vue'
import { usePackagesStore, useStatsStore } from '@/stores'

const statsStore = useStatsStore()
const packagesStore = usePackagesStore()

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

const updateFailed = computed(
  () => !!packagesStore.state.errorCurrentlyBuilding || !!statsStore.state.error
)
const lastMirrorSync = computed(
  () =>
    Math.floor(Date.now() / 1000) - (statsStore.state.stats?.last_mirror_timestamp || Date.now())
)

const packageArrays = reactive({
  building: computed(
    () =>
      packagesStore.state.currentlyBuildingPackages.filter((pkg) => pkg.status === 'building') || []
  ),
  queued: computed(
    () =>
      packagesStore.state.currentlyBuildingPackages.filter((pkg) => pkg.status === 'queued') || []
  ),
  built: computed(
    () =>
      packagesStore.state.currentlyBuildingPackages.filter((pkg) => pkg.status === 'built') || []
  )
})

let updateTimer: number | undefined
const startLastUpdatedTimer = () => {
  updateTimer = window.setInterval(() => {
    lastUpdatedSeconds.value++
  }, 1000)
}

const formatTimeAgo = (seconds: number): string => {
  if (seconds >= 3600) {
    return rtf.format(-Math.floor(seconds / 3600), 'hours')
  } else if (seconds >= 60) {
    return rtf.format(-Math.floor(seconds / 60), 'minutes')
  } else {
    return rtf.format(-seconds, 'seconds')
  }
}

onMounted(() => {
  startLastUpdatedTimer()
})

onUnmounted(() => {
  if (updateTimer) {
    clearInterval(updateTimer)
  }
})
</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;
}

.pulsating-circle-error {
  background-color: rgba(225, 64, 6, 0.94);
  border-radius: 50%;
  width: 12px;
  height: 12px;
}

.pulsating-circle-error:before {
  content: '';
  display: block;
  width: 200%;
  height: 200%;
  box-sizing: border-box;
  margin-left: -50%;
  margin-top: -50%;
  border-radius: 50%;
  background-color: rgba(225, 64, 6, 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;
}

.circle-offset {
  transform: translateY(10px); /* Preserves vertical shift as needed */
}

.flex-circle {
  flex-shrink: 0;
  flex-grow: 0;
  width: 12px;
  height: 12px;
  border-radius: 50%;
}

@-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>
