<!--suppress JSValidateTypes -->
<template>
  <div>
    <DataTable
      :value="users"
      datakey="id"
      :loading="isPending"
      scrollable
      :scrollHeight="`calc(100vh - ${elementHeights}px)`"
      selectionMode="single"
      :pt="{
        header: { id: 'datatable_header' },
        footer: { id: 'datatable_footer' },
        tbody: 'text-base'
      }"
      @rowSelect="showUserEdit"
    >
      <Column
        v-for="column of columns"
        :key="column"
        :field="column"
        :header="_upperCase(column)"
      >
        <template #body="slotProps">
          <template v-if="_isDate(slotProps.data?.[column])">
            {{ toNumericDate(slotProps.data?.[column]) }}
          </template>

          <template v-else>
            {{ slotProps.data?.[column] }}
          </template>
        </template>
      </Column>

      <template #loading>
        <SpinnerModal
          :visible="true"
          maskClass="bg-surface!"
        />
      </template>

      <template #footer>
        <UserToolbar
          :class="isPending && 'hidden'"
          :count="count"
        />
      </template>
    </DataTable>
  </div>
</template>

<script setup>
definePageMeta({
  name: "admin:users",
  middleware: ["signed-in", "admin"]
})

const { data: users, isPending } = useQuery(userListQuery)

const columns = ["email", "name", "username", "role", "createdAt"]
const count = computed(() => users?.value ? users.value.length : 0)

const DEFAULT_ELEMENT_HEIGHTS = 109
const elementHeights = ref(DEFAULT_ELEMENT_HEIGHTS)

onMounted(() => updateElementHeights())
onUpdated(() => updateElementHeights())

function toNumericDate(date) {
  return new Intl.DateTimeFormat(undefined, {
    year: "numeric",
    month: "numeric",
    day: "numeric",
    hour: "numeric",
    minute: "numeric"
  }).format(date)
}

async function showUserEdit({ data: { id: userId } }) {
  await navigateTo({ name: 'admin:userEdit', params: { userId } })
}

function updateElementHeights() {
  elementHeights.value = totalElementHeights()
}

function totalElementHeights() {
  // total height of non-datatable elements (in pixels)
  const elements = ["navbar", "datatable_footer"]

  // noinspection JSUnresolvedReference
  let totalHeights = _reduce(
    elements,
    (acc, element) => acc + document?.getElementById(element)?.offsetHeight,
    0
  )

  // plus 16px [--spacing(4)] navbar bottom margin
  totalHeights += 16

  return _isNaN(totalHeights) ? DEFAULT_ELEMENT_HEIGHTS : totalHeights
}
</script>

<style scoped></style>
