<template>
  <div ref="container" class="bms-pagination" tabcurrentPage="0">
    <div class="bms-pagination__select">
      {{ selectLabel }}
      <BmsSelect
        v-model="size"
        :small="small"
        :options="
          sizes.map((size: number) => ({ label: size.toString(), value: size }))
        "
      />
    </div>

    <div class="bms-pagination__status">
      <slot
        :first="size * currentPage + 1"
        :current-last="lastItemNumber"
        :last="total"
      >
        {{ size * currentPage + 1 }} à {{ lastItemNumber
        }}<template v-if="total !== Infinity"> / {{ total }}</template>
        <template v-else> ...</template>
      </slot>
    </div>

    <div class="bms-pagination__actions">
      <BmsIconButton
        color="neutral"
        @click="goToFirst"
        :disabled="currentPage === 0"
      >
        <ChevronFirst />
      </BmsIconButton>
      <BmsIconButton @click="goToPrevious" :disabled="currentPage === 0">
        <ChevronLeft />
      </BmsIconButton>
      <BmsIconButton
        @click="goToNext"
        :disabled="currentPage === pages - 1 || pages === 0"
      >
        <ChevronRight />
      </BmsIconButton>
      <BmsIconButton
        @click="goToLast"
        :disabled="
          currentPage === pages - 1 || pages === 0 || total === Infinity
        "
      >
        <ChevronLast />
      </BmsIconButton>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { BmsSelect } from '@/index';

import {
  ChevronFirst,
  ChevronLast,
  ChevronLeft,
  ChevronRight,
} from 'lucide-vue-next';
import { computed, ref } from 'vue';
import BmsIconButton from '../button/BmsIconButton.vue';

interface BmsPaginationProps {
  currentSize: number;
  sizes: number[];
  total: number;
  currentPage: number;
  pages: number;
  selectLabel?: string;
  small?: boolean;
}
const props = withDefaults(defineProps<BmsPaginationProps>(), {
  selectLabel: 'Éléments par page :',
  small: false,
});

const emit = defineEmits<{
  (e: 'update:currentSize', value: number): void;
  (e: 'next'): void;
  (e: 'prev'): void;
  (e: 'go', page: number): void;
}>();

const container = ref<HTMLInputElement | null>(null);

const lastItemNumber = computed(() => {
  const currentLastIndex = size.value + size.value * props.currentPage;

  return currentLastIndex <= props.total ? currentLastIndex : props.total;
});

const size = computed({
  get() {
    return props.currentSize;
  },
  set(value: number) {
    emit('update:currentSize', value);
  },
});

const focusContainer = () => {
  /*
    buttons lose focus on disable
    keep focus on the component after action
  */
  container.value?.focus();
};

const goToFirst = () => {
  focusContainer();
  emit('go', 0);
};

const goToPrevious = () => {
  if (props.currentPage === 1) {
    focusContainer();
  }
  emit('prev');
};

const goToNext = () => {
  if (props.currentPage === props.pages - 1) {
    focusContainer();
  }
  emit('next');
};

const goToLast = () => {
  focusContainer();
  emit('go', props.pages - 1);
};
</script>

<style lang="scss" scoped>
.bms-pagination {
  font-size: 0.88em;
  display: flex;
  gap: 2em;
  justify-content: flex-end;
  align-items: baseline;

  &__select {
    display: flex;
    gap: 1em;
    align-items: baseline;

    :deep(.field__wrapper) {
      min-width: 10em;
      width: 10em;
    }
  }
}
</style>
