<script setup lang="ts">
import type { RequestParams } from 'nocodb-sdk'
import { ExportTypes } from 'nocodb-sdk'
import {
  ActiveViewInj,
  FieldsInj,
  IsPublicInj,
  MetaInj,
  extractSdkResponseErrorMsg,
  iconMap,
  inject,
  message,
  ref,
  storeToRefs,
  useBase,
  useNuxtApp,
} from '#imports'

const isPublicView = inject(IsPublicInj, ref(false))

const fields = inject(FieldsInj, ref([]))

const baseStore = useBase()
const { base } = storeToRefs(baseStore)

const { $api } = useNuxtApp()

const meta = inject(MetaInj, ref())

const selectedView = inject(ActiveViewInj)

const { activeNestedFilters: nestedFilters, activeSorts: sorts } = storeToRefs(useViewsStore())

const isExportingType = ref<ExportTypes | undefined>(undefined)

const exportFile = async (exportType: ExportTypes) => {
  let offset = 0
  let c = 1
  const responseType = exportType === ExportTypes.EXCEL ? 'base64' : 'blob'

  isExportingType.value = exportType

  const XLSX = await import('xlsx')
  const FileSaver = await import('file-saver')

  try {
    while (!isNaN(offset) && offset > -1) {
      let res
      if (isPublicView.value) {
        const { exportFile: sharedViewExportFile } = useSharedView()
        res = await sharedViewExportFile(fields.value, offset, exportType, responseType, {
          sortsArr: sorts.value,
          filtersArr: nestedFilters.value,
        })
      } else {
        res = await $api.dbViewRow.export(
          'noco',
          base.value?.id as string,
          meta.value?.id as string,
          selectedView?.value.id as string,
          exportType,
          {
            responseType,
            query: {
              fields: fields.value.map((field) => field.title),
              offset,
              sortArrJson: JSON.stringify(sorts.value),
              filterArrJson: JSON.stringify(nestedFilters.value),
            },
          } as RequestParams,
        )
      }

      const { data, headers } = res

      if (exportType === ExportTypes.EXCEL) {
        const workbook = XLSX.read(data, { type: 'base64' })

        XLSX.writeFile(workbook, `${meta.value?.title}_exported_${c++}.xlsx`)
      } else if (exportType === ExportTypes.CSV) {
        const blob = new Blob([data], { type: 'text/plain;charset=utf-8' })

        FileSaver.saveAs(blob, `${meta.value?.title}_exported_${c++}.csv`)
      }

      offset = +headers['nc-export-offset']

      setTimeout(() => {
        isExportingType.value = undefined
      }, 200)
    }
  } catch (e: any) {
    message.error(await extractSdkResponseErrorMsg(e))
  }
}
</script>

<template>
  <div class="flex py-3 px-4 font-bold uppercase text-xs text-gray-500">{{ $t('labels.downloadData') }}</div>

  <a-menu-item class="!mx-1 !py-2 !rounded-md">
    <div
      v-e="['a:download:csv']"
      class="flex flex-row items-center nc-base-menu-item !py-0"
      @click.stop="exportFile(ExportTypes.CSV)"
    >
      <GeneralLoader v-if="isExportingType === ExportTypes.CSV" class="!max-h-4.5 !-mt-1 !mr-0.7" />
      <component :is="iconMap.csv" v-else />
      <!-- Download as CSV -->
      {{ $t('activity.downloadCSV') }}
    </div>
  </a-menu-item>

  <a-menu-item class="!mx-1 !py-2 !rounded-md">
    <div
      v-e="['a:download:excel']"
      class="flex flex-row items-center nc-base-menu-item !py-0"
      @click="exportFile(ExportTypes.EXCEL)"
    >
      <GeneralLoader v-if="isExportingType === ExportTypes.EXCEL" class="!max-h-4.5 !-mt-1 !mr-0.7" />
      <component :is="iconMap.excel" v-else />

      <!-- Download as XLSX -->
      {{ $t('activity.downloadExcel') }}
    </div>
  </a-menu-item>
</template>
