<script setup lang="ts">
import axios from 'axios'
import { type PaginatedType, UITypes } from 'nocodb-sdk'

const props = defineProps<{
  scrollLeft?: number
  paginationData: PaginatedType
  changePage: (page: number) => void
}>()

const emits = defineEmits(['update:paginationData'])

const { isViewDataLoading, isPaginationLoading } = storeToRefs(useViewsStore())

const isLocked = inject(IsLockedInj, ref(false))

const { changePage } = props

const vPaginationData = useVModel(props, 'paginationData', emits)

const { loadViewAggregate, updateAggregate, getAggregations, visibleFieldsComputed, displayFieldComputed } =
  useViewAggregateOrThrow()

const scrollLeft = toRef(props, 'scrollLeft')

const reloadViewDataHook = inject(ReloadViewDataHookInj)

const containerElement = ref()

watch(
  scrollLeft,
  (value) => {
    if (containerElement.value) {
      containerElement.value.scrollLeft = value
    }
  },
  {
    immediate: true,
  },
)

reloadViewDataHook?.on(async () => {
  await loadViewAggregate()
})

const count = computed(() => vPaginationData.value?.totalRows ?? Infinity)

const page = computed({
  get: () => vPaginationData?.value?.page ?? 1,
  set: async (p) => {
    isPaginationLoading.value = true
    try {
      await changePage?.(p)
      isPaginationLoading.value = false
    } catch (e) {
      if (axios.isCancel(e)) {
        return
      }
      isPaginationLoading.value = false
    }
  },
})

const size = computed({
  get: () => vPaginationData.value?.pageSize ?? 25,
  set: (size: number) => {
    if (vPaginationData.value) {
      // if there is no change in size then return
      if (vPaginationData.value?.pageSize && vPaginationData.value?.pageSize === size) {
        return
      }

      vPaginationData.value.pageSize = size

      if (vPaginationData.value.totalRows && page.value * size < vPaginationData.value.totalRows) {
        changePage?.(page.value)
      } else {
        changePage?.(1)
      }
    }
  },
})

const renderAltOrOptlKey = () => {
  return isMac() ? '⌥' : 'ALT'
}
</script>

<template>
  <div ref="containerElement" class="bg-gray-50 w-full pr-1 border-t-1 border-gray-200 overflow-x-hidden no-scrollbar flex h-9">
    <div class="sticky flex items-center bg-gray-50 left-0">
      <NcDropdown
        :disabled="[UITypes.SpecificDBType, UITypes.ForeignKey].includes(displayFieldComputed.column?.uidt!) || isLocked"
        overlay-class-name="max-h-96 relative scroll-container nc-scrollbar-md overflow-auto"
      >
        <div
          v-if="displayFieldComputed.field && displayFieldComputed.column?.id"
          class="flex items-center overflow-x-hidden hover:bg-gray-100 cursor-pointer text-gray-500 justify-end transition-all transition-linear px-3 py-2"
          :style="{
            'min-width': displayFieldComputed?.width,
            'max-width': displayFieldComputed?.width,
            'width': displayFieldComputed?.width,
          }"
        >
          <div class="flex relative justify-between gap-2 w-full">
            <div v-if="isViewDataLoading" class="nc-pagination-skeleton flex justify-center item-center min-h-10 min-w-16 w-16">
              <a-skeleton :active="true" :title="true" :paragraph="false" class="w-16 max-w-16" />
            </div>
            <NcTooltip v-else class="flex sticky items-center h-full">
              <template #title> {{ count }} {{ count !== 1 ? $t('objects.records') : $t('objects.record') }} </template>
              <span
                data-testid="grid-pagination"
                class="text-gray-500 text-ellipsis overflow-hidden pl-1 truncate nc-grid-row-count caption text-xs text-nowrap"
              >
                {{ Intl.NumberFormat('en', { notation: 'compact' }).format(count) }}
                {{ count !== 1 ? $t('objects.records') : $t('objects.record') }}
              </span>
            </NcTooltip>

            <template v-if="![UITypes.SpecificDBType, UITypes.ForeignKey].includes(displayFieldComputed.column?.uidt!)">
              <div
                v-if="!displayFieldComputed.field?.aggregation || displayFieldComputed.field?.aggregation === 'none'"
                class="text-gray-500 opacity-0 transition group-hover:opacity-100"
              >
                <GeneralIcon class="text-gray-500" icon="arrowDown" />
                <span class="text-[10px] font-semibold"> Summary </span>
              </div>
              <NcTooltip
                v-else-if="displayFieldComputed.value !== undefined"
                :style="{
                  maxWidth: `${displayFieldComputed?.width}`,
                }"
              >
                <div style="direction: rtl" class="flex gap-2 text-nowrap truncate overflow-hidden items-center">
                  <span class="text-gray-600 text-[12px] font-semibold">
                    {{
                      formatAggregation(
                        displayFieldComputed.field.aggregation,
                        displayFieldComputed.value,
                        displayFieldComputed.column,
                      )
                    }}
                  </span>
                  <span class="text-gray-500 text-[12px] leading-4">
                    {{ $t(`aggregation.${displayFieldComputed.field.aggregation}`) }}
                  </span>
                </div>

                <template #title>
                  <div class="flex gap-2 text-nowrap overflow-hidden items-center">
                    <span class="text-[12px] leading-4">
                      {{ $t(`aggregation.${displayFieldComputed.field.aggregation}`) }}
                    </span>

                    <span class="text-[12px] font-semibold">
                      {{
                        formatAggregation(
                          displayFieldComputed.field.aggregation,
                          displayFieldComputed.value,
                          displayFieldComputed.column,
                        )
                      }}
                    </span>
                  </div>
                </template>
              </NcTooltip>
            </template>
          </div>
        </div>

        <template #overlay>
          <NcMenu v-if="displayFieldComputed.field && displayFieldComputed.column?.id">
            <NcMenuItem
              v-for="(agg, index) in getAggregations(displayFieldComputed.column)"
              :key="index"
              @click="updateAggregate(displayFieldComputed.column.id, agg)"
            >
              <div class="flex !w-full text-[13px] text-gray-800 items-center justify-between">
                {{ $t(`aggregation_type.${agg}`) }}

                <GeneralIcon v-if="displayFieldComputed.field?.aggregation === agg" class="text-brand-500" icon="check" />
              </div>
            </NcMenuItem>
          </NcMenu>
        </template>
      </NcDropdown>
    </div>

    <template v-for="({ field, width, column, value }, index) in visibleFieldsComputed" :key="index">
      <NcDropdown
        v-if="field && column?.id"
        :disabled="[UITypes.SpecificDBType, UITypes.ForeignKey].includes(column?.uidt!) || isLocked"
        overlay-class-name="max-h-96 relative scroll-container nc-scrollbar-md overflow-auto"
      >
        <div
          class="flex items-center overflow-x-hidden justify-end group hover:bg-gray-100 cursor-pointer text-gray-500 transition-all transition-linear px-3 py-2"
          :style="{
            'min-width': width,
            'max-width': width,
            'width': width,
          }"
        >
          <template v-if="![UITypes.SpecificDBType, UITypes.ForeignKey].includes(column?.uidt!)">
            <div
              v-if="field?.aggregation === 'none' || field?.aggregation === null"
              class="text-gray-500 opacity-0 transition group-hover:opacity-100"
            >
              <GeneralIcon class="text-gray-500" icon="arrowDown" />
              <span class="text-[10px] font-semibold"> Summary </span>
            </div>

            <NcTooltip
              v-else-if="value !== undefined"
              :style="{
                maxWidth: `${field?.width}px`,
              }"
            >
              <div class="flex gap-2 truncate text-nowrap overflow-hidden items-center">
                <span class="text-gray-500 text-[12px] leading-4">
                  {{ $t(`aggregation.${field.aggregation}`).replace('Percent ', '') }}
                </span>

                <span class="text-gray-600 font-semibold text-[12px]">
                  {{ formatAggregation(field.aggregation, value, column) }}
                </span>
              </div>

              <template #title>
                <div class="flex gap-2 text-nowrap overflow-hidden items-center">
                  <span class="text-[12px] leading-4">
                    {{ $t(`aggregation.${field.aggregation}`).replace('Percent ', '') }}
                  </span>

                  <span class="font-semibold text-[12px]">
                    {{ formatAggregation(field.aggregation, value, column) }}
                  </span>
                </div>
              </template>
            </NcTooltip>
          </template>
        </div>

        <template #overlay>
          <NcMenu>
            <NcMenuItem v-for="(agg, index) in getAggregations(column)" :key="index" @click="updateAggregate(column.id, agg)">
              <div class="flex !w-full text-[13px] text-gray-800 items-center justify-between">
                {{ $t(`aggregation_type.${agg}`) }}

                <GeneralIcon v-if="field?.aggregation === agg" class="text-brand-500" icon="check" />
              </div>
            </NcMenuItem>
          </NcMenu>
        </template>
      </NcDropdown>
    </template>

    <div class="!pl-8 pr-60 !w-8 h-1">‎</div>

    <div class="fixed h-9 bg-white border-l-1 border-gray-200 px-1 flex items-center right-0">
      <NcPaginationV2
        v-if="count !== Infinity"
        v-model:current="page"
        v-model:page-size="size"
        class="xs:(mr-2)"
        :total="+count"
        entity-name="grid"
        :prev-page-tooltip="`${renderAltOrOptlKey()}+←`"
        :next-page-tooltip="`${renderAltOrOptlKey()}+→`"
        :first-page-tooltip="`${renderAltOrOptlKey()}+↓`"
        :last-page-tooltip="`${renderAltOrOptlKey()}+↑`"
        :show-size-changer="true"
      />
    </div>
  </div>
</template>

<style scoped lang="scss">
:deep(.nc-menu-item-inner) {
  @apply w-full;
}

.nc-grid-pagination-wrapper {
  .ant-pagination-item-active {
    a {
      @apply text-sm !text-gray-700 !hover:text-gray-800;
    }
  }
}
</style>

<style lang="scss"></style>
