<template>
  <v-row :style="mobile ? '' : `height: ${ROW_HEIGHT}px`" width="100%">
    <v-col class="v-col-12 v-col-sm-2 v-col-lg-2">
      <v-text-field
        v-model="pkgbase"
        clearable
        color="primary"
        placeholder="Search Pkgbase"
        variant="outlined"></v-text-field>
    </v-col>
    <v-col class="v-col-12 v-col-sm-2 v-col-lg-2 mt-n6 mt-sm-0">
      <v-select
        v-model="repo"
        :items="REPO_ITEMS"
        clearable
        color="primary"
        placeholder="Any Repo"
        variant="outlined"></v-select>
    </v-col>
    <v-col class="v-col-12 v-col-sm-2 v-col-lg-3 mt-n6 mt-sm-0">
      <v-select
        v-model="status"
        :items="STATUS_ITEMS"
        chips
        closable-chips
        color="primary"
        density="default"
        item-title="title"
        item-value="value"
        multiple
        placeholder="Any Status"
        return-object
        variant="outlined"></v-select>
    </v-col>
    <v-col class="v-col-12 v-col-sm-2 v-col-lg-2 mt-n6 mt-sm-0">
      <v-switch v-model="exact" color="primary" label="Exact search"></v-switch>
    </v-col>
    <v-col :class="mobile ? 'mt-n6' : ''" :cols="mobile ? 12 : 'auto'" class="ms-auto">
      <v-pagination
        v-model="page"
        :length="totalPages"
        :total-visible="mobile ? undefined : 3"
        active-color="primary"
        density="comfortable"
        start="1"
        variant="text"></v-pagination>
    </v-col>
  </v-row>
</template>

<script lang="ts" setup>
import { useDisplay } from 'vuetify'
import { REPO_ITEMS, ROW_HEIGHT, STATUS_ITEMS } from '@/config/constants'
import { usePackagesStore } from '@/stores'
import { computed, onMounted, ref, watch } from 'vue'
import { components } from '@/api'

const { mobile } = useDisplay()
const packagesStore = usePackagesStore()

const page = ref<number>(1)
const pkgbase = ref<string>()
const repo = ref<string>()
const status = ref<{ title: string; value: string }[]>([])
const exact = ref<boolean>()

const totalPages = computed(() => Math.ceil(packagesStore.state.total / packagesStore.state.limit))

const updateFilter = (pageVal?: number) => {
  if (packagesStore.state.loading) return

  if (pageVal) {
    page.value = pageVal
  } else {
    page.value = 1
  }

  packagesStore.setFilters(
    {
      exact: exact.value,
      status: status.value.map(
        (state) => state.value as components['schemas']['Package']['status']
      ),
      pkgbase: pkgbase.value !== null ? pkgbase.value : undefined,
      repo: repo.value
    },
    page.value
  )
}

const initFilters = () => {
  page.value = packagesStore.state.offset / packagesStore.state.limit + 1
  pkgbase.value = packagesStore.state.filters.pkgbase
  repo.value = packagesStore.state.filters.repo
  exact.value = packagesStore.state.filters.exact
  if (packagesStore.state.filters.status) {
    for (const state of packagesStore.state.filters.status) {
      if (state) {
        status.value.push({ title: state.toUpperCase(), value: state.toLowerCase() })
      }
    }
  }
}

watch(
  () => page.value,
  (pageVal) => {
    packagesStore.goToPage(pageVal)
  }
)

// Watcher for pkgbase with debounce
let pkgbaseTimeout: ReturnType<typeof setTimeout> | null = null
watch(
  () => pkgbase.value,
  () => {
    if (pkgbaseTimeout) clearTimeout(pkgbaseTimeout)
    pkgbaseTimeout = setTimeout(() => {
      updateFilter()
    }, 300)
  }
)

// Watcher for other filters (repo, status, exact) without debounce
watch(
  [() => repo.value, () => status.value?.map((state) => state.value), () => exact.value],
  () => {
    // Cancel pending pkgbase debounce if any
    if (pkgbaseTimeout) {
      clearTimeout(pkgbaseTimeout)
      pkgbaseTimeout = null
    }
    updateFilter()
  }
)

onMounted(() => {
  initFilters()
})
</script>
