<template>
  <ASection :title="t('showTimeslots.title')">
    <template #header>
      <TimeSlotFilter
        v-model:start-date="formattedLocalStartTime"
        v-model:direction="direction"
        class="tw-flex tw-gap-3 tw-items-center tw-ml-auto"
      />
    </template>

    <div class="aura-table-wrapper">
      <table ref="tableEl" class="aura-table">
        <thead class="tw-sticky tw-top-0 tw-z-10 tw-bg-white">
          <tr>
            <th>{{ t('emissionTable.title') }}</th>
            <th>{{ t('emissionTable.start') }}</th>
            <th>{{ t('emissionTable.duration') }}</th>
            <th>{{ t('emissionTable.playlist') }}</th>
            <th class="tw-p-0" />
          </tr>
        </thead>

        <tbody>
          <template v-for="timeslot in result.items" :key="timeslot.id">
            <TimeSlotRow
              class="tw-transition hover:tw-bg-gray-50"
              :timeslot="timeslot"
              :is-next-up="nextBroadcastedTimeslot?.id === timeslot.id"
              :is-on-air="onAirTimeslot?.id === timeslot.id"
            />
          </template>
          <template v-if="!hasTimeslots">
            <tr>
              <td colspan="4">
                <p class="tw-text-center tw-p-3 tw-m-0">
                  {{ t('showTimeslots.noTimeslotsScheduled') }}
                </p>
              </td>
            </tr>
          </template>
        </tbody>
      </table>

      <div
        class="tw-flex tw-flex-wrap tw-gap-3 tw-items-center tw-px-6 tw-mt-3 tw-py-3 tw-border-0 tw-border-t tw-border-solid tw-border-gray-200 empty:tw-hidden"
      >
        <PaginationRange v-if="result.count > 0" :pagination-data="result" />
        <FormGroup v-slot="attrs" class="tw-ml-auto tw-m-0 last:tw-mr-0">
          <label class="tw-flex tw-items-center tw-gap-3 tw-m-0">
            <span>{{ t('showTimeslots.numberOfSlots') }}</span>
            <input
              v-model.lazy="limit"
              v-bind="attrs"
              type="number"
              min="1"
              step="1"
              class="tw-w-[80px] tw-self-center"
            />
          </label>
        </FormGroup>
        <Pagination v-model="page" :items-per-page="result.itemsPerPage" :count="result.count" />
      </div>
    </div>
  </ASection>
</template>

<script lang="ts" setup>
import { usePaginatedList } from '@rokoli/bnb/drf'
import { useNow, useStorage } from '@vueuse/core'
import { formatISO, roundToNearestMinutes } from 'date-fns'
import { computed, ref, watch, watchEffect } from 'vue'

import { useI18n } from '@/i18n'
import { Show } from '@/types'
import { useFormattedISODate, useQuery } from '@/util'
import { useTimeSlotStore } from '@/stores/timeslots'

import TimeSlotFilter from './TimeSlotFilter.vue'
import TimeSlotRow from '@/components/shows/TimeSlotRow.vue'
import Pagination from '@/components/generic/Pagination.vue'
import PaginationRange from '@/components/generic/PaginationRange.vue'
import ASection from '@/components/generic/ASection.vue'
import FormGroup from '@/components/generic/FormGroup.vue'

const DEFAULT_TIMESLOT_LIMIT = parseInt(
  import.meta.env.VUE_APP_TIMESLOT_FILTER_DEFAULT_NUMSLOTS ?? 5,
)

defineOptions({
  compatConfig: { MODE: 3 },
  ATTR_FALSE_VALUE: false,
})

const props = defineProps<{
  show: Show
}>()

const { t } = useI18n()
const timeslotStore = useTimeSlotStore()

const now = useNow({ interval: 60_000 })
const page = ref(1)
const direction = ref<'future' | 'past'>('future')
const limit = useStorage('aura:timeslotList:timeslotsPerPage', DEFAULT_TIMESLOT_LIMIT)
const startTime = ref(roundToNearestMinutes(new Date()))
const formattedStartTime = useFormattedISODate(startTime)
const formattedLocalStartTime = useFormattedISODate(startTime, now, { stripOffset: true })
const tableEl = ref<HTMLTableElement>()
const hasPageBeenModified = ref(false)
const { result } = usePaginatedList(timeslotStore.listIsolated, page, limit, {
  events: timeslotStore.events,
  query: useQuery(() => ({
    showIds: props.show.id,
    endsAfter: direction.value === 'future' ? formattedStartTime.value : undefined,
    endsBefore: direction.value === 'past' ? formattedStartTime.value : undefined,
    order: direction.value === 'future' ? 'start' : '-start',
  })),
})
const hasTimeslots = computed(() => result.value.count > 0)
const onAirTimeslot = computed(() => {
  const _now = formatISO(now.value)
  return result.value.items.find((t) => t.start <= _now && _now < t.end) ?? null
})

const currentResultTime = ref(new Date())
const { result: currentResult } = usePaginatedList(timeslotStore.listIsolated, 1, 1, {
  events: timeslotStore.events,
  query: useQuery(() => ({
    showIds: props.show.id,
    startsAfter: formatISO(currentResultTime.value),
    order: 'start',
  })),
})
const nextBroadcastedTimeslot = computed(() => currentResult.value.items[0] ?? null)
watch([onAirTimeslot, useNow({ interval: 15 * 60_000 })], () => {
  // reload from usePaginatedList doesn’t cut it, because we actually need to change the query
  currentResultTime.value = new Date()
})

watchEffect(() => {
  if (page.value !== 1) {
    hasPageBeenModified.value = true
  }
  if (hasPageBeenModified.value && tableEl.value) {
    tableEl.value.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'start' })
  }
})
</script>