<template>
    <v-pagination :density="density"
                  :disabled="disabled"
                  :total-visible="totalVisible ?? 7"
                  :length="totalPageCount"
                  v-model="currentPage">
        <template #item="{ key, page, isActive }">
            <v-btn variant="text"
                   :density="density"
                   :disabled="disabled"
                   :icon="true"
                   :color="isActive ? 'primary' : 'default'"
                   @click="currentPage = key;"
                   v-if="isNumber(key)"
            >
                <span>{{ formatNumberToLocalizedNumerals(key) }}</span>
            </v-btn>
            <v-btn variant="text"
                   color="default"
                   :density="density"
                   :disabled="disabled"
                   :icon="true"
                   v-if="!isNumber(key)"
            >
                <span>{{ page }}</span>
                <v-menu activator="parent"
                        :disabled="disabled"
                        :close-on-content-click="false"
                        v-model="showMenus[key]">
                    <v-list>
                        <v-list-item class="text-sm" :density="density">
                            <v-list-item-title class="cursor-pointer">
                                <v-autocomplete width="110"
                                                item-title="name"
                                                item-value="value"
                                                auto-select-first
                                                :density="density"
                                                :items="allPages"
                                                :custom-filter="customFilter"
                                                :no-data-text="tt('No results')"
                                                v-model="currentPage"/>
                            </v-list-item-title>
                        </v-list-item>
                    </v-list>
                </v-menu>
            </v-btn>
        </template>
    </v-pagination>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import type { InternalItem, FilterMatch } from 'vuetify/lib/composables/filter.d.ts';

import { useI18n } from '@/locales/helpers.ts';

import { type NameNumeralValue, keys } from '@/core/base.ts';

import { isNumber } from '@/lib/common.ts';
import type { ComponentDensity } from '@/lib/ui/desktop.ts';

const props = defineProps<{
    density?: ComponentDensity;
    disabled?: boolean;
    totalPageCount: number;
    totalVisible?: number;
    modelValue: number;
}>();

const emit = defineEmits<{
    (e: 'update:modelValue', value: number): void;
}>();

const { tt, formatNumberToLocalizedNumerals } = useI18n();

const showMenus = ref<Record<string, boolean>>({});

const allPages = computed<NameNumeralValue[]>(() => {
    const pages: NameNumeralValue[] = [];

    for (let i = 1; i <= props.totalPageCount; i++) {
        pages.push({ value: i, name: formatNumberToLocalizedNumerals(i) });
    }

    return pages;
});

const currentPage = computed<number>({
    get: () => props.modelValue,
    set: (value) => {
        if (value && value >= 1 && value <= props.totalPageCount) {
            emit('update:modelValue', value);

            for (const key of keys(showMenus.value)) {
                showMenus.value[key] = false;
            }
        }
    }
});

function customFilter(value: string, query: string, item?: InternalItem): FilterMatch {
    if (!item) {
        return false;
    }

    const page = item.value as number;
    return page.toString(10).includes(query);
}
</script>
