<template>
  <nav
    v-if="length > 1"
    class="ui-pagination"
  >
    <div class="ui-pagination__items">

      <template v-if="length <= 6">
        <component
          v-for="number in length"
          :is="number === activeNumber ? 'span' : nuxtLink"
          :key="`pagination-${number}`"
          :class="[
            number === activeNumber && 'ui-pagination__item--active',
            theme && `ui-btn --${theme}`
          ]"
          :to="number === activeNumber ? undefined : linkTo(number)"
          class="ui-pagination__item"
        >
          {{ number }}
        </component>
      </template>

      <template v-else>
        <component
          :is="1 === activeNumber ? 'span' : nuxtLink"
          :class="[
            1 === activeNumber && 'ui-pagination__item--active',
            theme && `ui-btn --${theme}`
          ]"
          :to="1 === activeNumber ? undefined : linkTo(1)"
          class="ui-pagination__item"
        >1
        </component>
        <span
          v-if="activeNumber > 4"
          :class="[
            theme && `ui-btn --${theme}`
          ]"
          class="ui-pagination__item ui-pagination__item--empty"
        >...</span>
        <component
          v-else
          :is="2 === activeNumber ? 'span' : nuxtLink"
          :class="[
            2 === activeNumber && 'ui-pagination__item--active',
            theme && `ui-btn --${theme}`
          ]"
          :to="2 === activeNumber ? undefined : linkTo(2)"
          class="ui-pagination__item"
        >2
        </component>
        <component
          v-for="number in activeNumbers"
          :is="number === activeNumber ? 'span' : nuxtLink"
          :key="`pagination-${number}`"
          :class="[
            number === activeNumber && 'ui-pagination__item--active',
            theme && `ui-btn --${theme}`
          ]"
          :to="number === activeNumber ? undefined : linkTo(number)"
          class="ui-pagination__item"
        >
          {{ number }}
        </component>
        <span
          v-if="activeNumber < length - 3"
          :class="[
            theme && `ui-btn --${theme}`
          ]"
          class="ui-pagination__item ui-pagination__item--empty"
        >...</span>
        <component
          v-else
          :is="length - 1 === activeNumber ? 'span' : nuxtLink"
          :class="[
            length - 1 === activeNumber && 'ui-pagination__item--active',
            theme && `ui-btn --${theme}`
          ]"
          :to="length - 1 === activeNumber ? undefined : linkTo(length - 1)"
          class="ui-pagination__item"
        >{{ length - 1 }}
        </component>
        <component
          :is="length === activeNumber ? 'span' : nuxtLink"
          :class="[
            length === activeNumber && 'ui-pagination__item--active',
            theme && `ui-btn --${theme}`
          ]"
          :to="length === activeNumber ? undefined : linkTo(length)"
          class="ui-pagination__item"
        >
          {{ length }}
        </component>
      </template>
    </div>
    <UiLink
      wide
      :to="linkTo(previousValue)"
      :disabled="activeNumber <= 1"
      class="ui-pagination__prev"
      theme="primary"
    >
      <UiIcon
        v-if="arrowIcon"
        name="angle-left"
        size="16"
      />
      {{ t('previous' )}}
    </UiLink>
    <UiLink
      wide
      :disabled="activeNumber >= length"
      :to="linkTo(nextValue)"
      class="ui-pagination__next"
      theme="primary"
    >
      {{ t('next') }}
      <UiIcon
        v-if="arrowIcon"
        name="angle-right"
        size="16"
      />
    </UiLink>
  </nav>
</template>

<script setup lang="ts">
import type { ButtonThemes } from '../../types';
import { getPaginationNumbers } from '../../utils/ui-pagination/get-pagination-numbers';
import { getPaginationLink } from '../../utils/ui-pagination/get-pagination-link';

const props = withDefaults(defineProps<{
  prefix?: string
  theme?: ButtonThemes
  total: number
  perPage?: number | string
  limit?: number
  arrowIcon?: boolean
}>(), {
  prefix: 'page',
  perPage: 48,
});

const { t } = useI18n();
const route = useRoute();
const nuxtLink = resolveComponent('NuxtLink');

const length = computed(() => {
  return props.limit ? Math.min(props.total, props.limit) : props.total;
});

const activeNumber = computed(() => {
  const n = Number(route.query[props.prefix]);
  return !n || n < 1 ? 1 : n;
});

const previousValue = computed(() => {
  return activeNumber.value > 1 ? activeNumber.value - 1 : activeNumber.value;
});

const nextValue = computed(() => {
  return activeNumber.value !== length.value ? activeNumber.value + 1 : activeNumber.value;
});

const activeNumbers = computed(() => getPaginationNumbers(activeNumber.value, length.value));

watchEffect(() => {
  if (activeNumber.value > length.value && props.total > 0) {
    navigateTo(linkTo(length.value));
  }
});

function linkTo(value: string | number) {
  return getPaginationLink(value, props.prefix, route.path, route.query);
}

watch(() => route.query['page'], () => {
  document.documentElement.querySelector('#anchor')?.scrollIntoView({ behavior: 'instant' });
});

// canonical/hreflang выпускает app.vue — отсюда уходит только факт, который знает лишь пагинация
useSetSeoOverride(() => ({ alonePage: props.total === 1 }));
</script>

<style lang="scss">
.ui-pagination {
  display: grid;
  margin: auto auto 0;
  gap: 12px;
  width: 100%;
  align-items: center;

  @include to-br(sm) {
    grid-template-columns: 1fr 1fr;
  }

  @include from-br(sm) {
    width: max-content;
    grid-auto-flow: column;
    gap: 8px;
  }
}

.ui-pagination__items {
  display: grid;
  grid-auto-flow: column;
  gap: 8px;
  grid-column: 1/3;
  grid-row: 2;
  overflow: hidden;
  margin: 0 auto;

  @include from-br(sm) {
    grid-column: 2;
    grid-row: 1;
  }
}

.ui-pagination__prev {
  grid-column: 1;
  grid-row: 2;

  @include from-br(sm) {
    grid-row: 1;
    grid-column: 1;
  }
}

.ui-pagination__next {
  grid-column: 2;
  grid-row: 2;

  @include from-br(sm) {
    grid-row: 1;
    grid-column: 3;
  }
}

.ui-pagination__item {
  --size: 40px;

  display: grid;
  place-content: center;
  min-width: var(--size);
  height: var(--size);
  padding-inline: $spacing;
  background-color: $pagination-bg;
  flex-grow: 1;
  text-align: center;
  color: $pagination-text;
  user-select: none;
  border-radius: $radius;

  @include hover(background-color, color) {
    background-color: $pagination-bg--hover;
    color: $pagination-text--hover;
  }
}

.ui-pagination__item.ui-pagination__item--empty {
  background-color: transparent;
  pointer-events: none;
  user-select: none;
}

.ui-pagination__item.ui-pagination__item--active {
  background-color: $pagination-bg--active;
  color: $pagination-text--active;
}

.ui-pagination__next,
.ui-pagination__prev {
  font: inherit;
  font-weight: 500;

  @include to-br(sm) {
    grid-row: 1;
    height: 48px;
  }
}

.ui-pagination__next.--disabled,
.ui-pagination__prev.--disabled {
  pointer-events: none;

  @include to-br(sm) {
    background-color: $pagination-bg--disabled;
    color: $pagination-text--disabled;
    opacity: 1;
  }

  @include from-br(sm) {
    opacity: 0;
  }
}
</style>
