<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
  showSizeChanger?: boolean
  customLabel?: string
  totalRows?: number
  depth?: number
  disablePagination?: boolean
  selectedCellCount?: number
}>()

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

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

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

const { changePage, customLabel } = props

const { showSizeChanger, disablePagination, selectedCellCount } = toRefs(props)

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

const { metas } = useMetas()

const { t } = useI18n()

const baseStore = useBase()

const { isMysql, isPg } = baseStore

const { meta, isViewOperationsAllowed } = useSmartsheetStoreOrThrow()

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

const scrollLeft = toRef(props, 'scrollLeft')

const containerElement = ref()

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

const count = computed(() => {
  if (selectedCellCount.value && selectedCellCount.value > 1) {
    return selectedCellCount.value
  }

  return vPaginationData.value?.totalRows ?? Infinity
})

const page = computed({
  get: () => vPaginationData?.value?.page ?? 1,
  set: async (p) => {
    if (disablePagination.value) {
      return
    }
    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 getAddnlMargin = (depth: number, ignoreCondition = false) => {
  if (!ignoreCondition ? (scrollLeft.value ?? 0) < 30 : true) {
    switch (depth) {
      case 3:
        return 26
      case 2:
        return 17
      case 1:
        return 8
      default:
        return 0
    }
  }
  return 0
}

const getCountWithLabel = (defaultCount: number) => {
  let labelCount = defaultCount

  if (selectedCellCount.value && selectedCellCount.value > 1) {
    labelCount = selectedCellCount.value
  }

  return {
    count: labelCount,
    label:
      selectedCellCount.value && selectedCellCount.value > 1
        ? t('labels.cellsSelected')
        : customLabel || (labelCount !== 1 ? t('objects.records') : t('objects.record')),
  }
}
</script>

<template>
  <div
    ref="containerElement"
    class="bg-nc-bg-gray-extralight w-full pr-1 border-t-1 border-nc-border-gray-medium overflow-x-hidden no-scrollbar flex h-9"
  >
    <div class="sticky flex items-center bg-nc-bg-gray-extralight left-0">
      <NcDropdown
        :disabled="[UITypes.SpecificDBType, UITypes.ForeignKey,  UITypes.Button].includes(displayFieldComputed.column?.uidt!) || isLocked || !isViewOperationsAllowed"
        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 text-nc-content-gray-muted justify-end transition-all transition-linear px-3 py-2"
          :class="{
            'cursor-pointer': !isLocked && isViewOperationsAllowed,
            'hover:bg-nc-bg-gray-light': isViewOperationsAllowed,
          }"
          :style="{
            'min-width': displayFieldComputed?.width,
            'max-width': displayFieldComputed?.width,
            'width': displayFieldComputed?.width,
            'margin-left': `${getAddnlMargin(depth ?? 0)}px`,
          }"
        >
          <div class="flex relative justify-between gap-2 w-full">
            <template v-if="!disablePagination">
              <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> {{ getCountWithLabel(count).count }} {{ getCountWithLabel(count).label }} </template>
                <span
                  data-testid="grid-pagination"
                  class="text-nc-content-gray-muted text-ellipsis overflow-hidden pl-1 truncate nc-grid-row-count caption text-xs text-nowrap"
                >
                  {{ Intl.NumberFormat('en', { notation: 'compact' }).format(getCountWithLabel(count).count) }}
                  {{ getCountWithLabel(count).label }}
                </span>
              </NcTooltip>
            </template>

            <template v-else-if="+totalRows >= 0 || (selectedCellCount && selectedCellCount > 1)">
              <NcTooltip class="flex sticky items-center h-full">
                <template #title>
                  {{ getCountWithLabel(totalRows ?? 0).count }} {{ getCountWithLabel(totalRows ?? 0).label }}
                </template>
                <span
                  data-testid="grid-pagination"
                  class="text-nc-content-gray-muted text-ellipsis overflow-hidden pl-1 truncate nc-grid-row-count caption text-xs text-nowrap"
                >
                  {{ Intl.NumberFormat('en', { notation: 'compact' }).format(getCountWithLabel(totalRows ?? 0).count) }}
                  {{ getCountWithLabel(totalRows ?? 0).label }}
                </span>
              </NcTooltip>
            </template>

            <template
              v-if="![UITypes.SpecificDBType, UITypes.ForeignKey, UITypes.Button].includes(displayFieldComputed.column?.uidt!)"
            >
              <div
                v-if="!displayFieldComputed.field?.aggregation || displayFieldComputed.field?.aggregation === 'none'"
                :class="{
                  'group-hover:opacity-100': !isLocked && isViewOperationsAllowed,
                }"
                class="text-nc-content-gray-muted opacity-0 transition"
              >
                <GeneralIcon class="text-nc-content-gray-muted" 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-nc-content-gray-subtle2 text-[12px] font-semibold">
                    {{
                      getFormattedAggrationValue(
                        displayFieldComputed.field.aggregation,
                        displayFieldComputed.value,
                        displayFieldComputed.column,
                        [],
                        {
                          meta,
                          metas,
                          isMysql,
                          isPg,
                          col: displayFieldComputed.column,
                        },
                      )
                    }}
                  </span>
                  <span class="text-nc-content-gray-muted 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">
                      {{
                        getFormattedAggrationValue(
                          displayFieldComputed.field.aggregation,
                          displayFieldComputed.value,
                          displayFieldComputed.column,
                          [],
                          {
                            meta,
                            metas,
                            isMysql,
                            isPg,
                            col: displayFieldComputed.column,
                          },
                        )
                      }}
                    </span>
                  </div>
                </template>
              </NcTooltip>
            </template>
          </div>
        </div>

        <template #overlay>
          <NcMenu v-if="displayFieldComputed.field && displayFieldComputed.column?.id" variant="small">
            <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-nc-content-gray items-center justify-between">
                {{ $t(`aggregation_type.${agg}`) }}

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

    <template v-for="({ field, width, column, value }, index) in visibleFieldsComputed" :key="index">
      <div
        v-if="index === 0 && scrollLeft > 30"
        :style="`width: ${getAddnlMargin(depth ?? 0, true)}px;min-width: ${getAddnlMargin(
          depth ?? 0,
          true,
        )}px;max-width: ${getAddnlMargin(depth ?? 0, true)}px`"
      ></div>
      <NcDropdown
        v-if="field && column?.id"
        :disabled="[UITypes.SpecificDBType, UITypes.ForeignKey,  UITypes.Button].includes(column?.uidt!) || isLocked || !isViewOperationsAllowed"
        overlay-class-name="max-h-96 relative scroll-container nc-scrollbar-md overflow-auto"
      >
        <div
          class="flex items-center overflow-hidden justify-end group text-nc-content-gray-muted transition-all transition-linear px-3 py-2"
          :class="{
            'cursor-pointer': !isLocked && isViewOperationsAllowed,
            'hover:bg-nc-bg-gray-light': isViewOperationsAllowed,
          }"
          :style="{
            'min-width': width,
            'max-width': width,
            'width': width,
          }"
        >
          <template v-if="![UITypes.SpecificDBType, UITypes.ForeignKey, UITypes.Button].includes(column?.uidt!)">
            <div
              v-if="field?.aggregation === 'none' || field?.aggregation === null"
              :class="{
                'group-hover:opacity-100': !isLocked && isViewOperationsAllowed,
              }"
              class="text-nc-content-gray-muted opacity-0 transition"
            >
              <GeneralIcon class="text-nc-content-gray-muted" 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-nc-content-gray-muted text-[12px] leading-4">
                  {{ $t(`aggregation.${field.aggregation}`).replace('Percent ', '') }}
                </span>

                <span class="text-nc-content-gray-subtle2 font-semibold text-[12px]">
                  {{
                    getFormattedAggrationValue(field.aggregation, value, column, [], {
                      meta,
                      metas,
                      isMysql,
                      isPg,
                      col: 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]">
                    {{
                      getFormattedAggrationValue(field.aggregation, value, column, [], {
                        meta,
                        metas,
                        isMysql,
                        isPg,
                        col: column,
                      })
                    }}
                  </span>
                </div>
              </template>
            </NcTooltip>
          </template>
        </div>

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

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

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

    <div
      v-if="!disablePagination"
      class="absolute h-9 bg-nc-bg-default border-l-1 border-nc-border-gray-medium px-1 flex items-center right-0"
    >
      <NcPaginationV2
        v-if="count !== Infinity"
        v-model:current="page"
        v-model:page-size="size"
        :show-size-changer="showSizeChanger"
        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()}+↑`"
      />
    </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-nc-content-gray-subtle !hover:text-nc-content-gray;
    }
  }
}
</style>

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