<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import type { DataTableColumns, PaginationProps } from 'naive-ui';
import { useI18n } from 'vue-i18n';
import {
  type TableBaseColumns,
  type TableFetchData,
  type TableFilterColumns,
  transformColumns,
  transformHeaderColumns
} from '.';
import type { TableColumnCheck } from '~/packages/hooks/src';

const route = useRoute();
const { t } = useI18n();

const title = t(route.meta.i18nKey as string);
const props = withDefaults(
  defineProps<{
    fetchData: TableFetchData;
    columns: TableBaseColumns;
    showHeaderOperation?: boolean;
    filterColumns?: TableFilterColumns;
  }>(),
  {
    filterColumns: () => []
  }
);
const emit = defineEmits<{
  (e: 'add'): void;
  (e: 'delete'): void;
}>();

const tableData = ref<any[]>([]);
const dataTableColumns = ref<DataTableColumns>(transformColumns(props.columns));
const headerTableColumns = ref<NaiveUI.TableColumnCheck[]>(transformHeaderColumns(props.columns));
const pagination = ref<PaginationProps>({
  page: 1,
  pageSize: 10,
  itemCount: 0,
  showSizePicker: true,
  pageSizes: [10, 20, 50, 100]
});

async function loadData(query?: Record<string, any>) {
  const page = pagination.value.page || 1;
  const pageSize = pagination.value.pageSize || 10;
  const { data } = await props.fetchData({
    pagination: {
      pageIndex: page,
      pageSize
    },
    filter: query
  });

  tableData.value = (data.value as any).data;
  pagination.value.itemCount = (data.value as any).pagination.total;
}

function handlePageChange(curPage: number) {
  pagination.value.page = curPage;
  loadData();
}
function handlePageSizeChange(curPageSize: number) {
  pagination.value.pageSize = curPageSize;
  loadData();
}
function handleSearch(form: Record<string, any>) {
  pagination.value.page = 1;
  loadData(form);
}
function handleUpdateColumns(columns: TableColumnCheck[]) {
  headerTableColumns.value = columns;
  const sortKeys = columns.map(col => col.key);

  const currentColumns: DataTableColumns = [...dataTableColumns.value];
  const sortedColumns = sortKeys.map(key => currentColumns.find(col => (col as any).key === key)).filter(Boolean);

  dataTableColumns.value = sortedColumns as DataTableColumns;
}

onMounted(() => {
  loadData();
});

defineExpose({
  reload: loadData
});
</script>

<template>
  <div class="space-y-5">
    <TableFilter v-if="filterColumns.length > 0" :columns="filterColumns" @confirm="handleSearch" />

    <div class="rounded-lg bg-white p-5 space-y-5 dark:bg-white/10">
      <TableHeaderOperation
        v-if="showHeaderOperation"
        :columns="headerTableColumns"
        @update:columns="handleUpdateColumns"
        @add="emit('add')"
        @refresh="loadData()"
        @delete="emit('delete')"
      >
        <template #prefix>
          <div class="text-lg font-bold">{{ title }}</div>
        </template>
      </TableHeaderOperation>

      <NDataTable
        :row-key="row => (row as any).id"
        :scroll-x="2000"
        :columns="dataTableColumns"
        :data="tableData"
        :pagination="pagination"
        :bordered="false"
        :on-update:page="handlePageChange"
        :on-update:page-size="handlePageSizeChange"
      />
    </div>
  </div>
</template>

<style lang="css" scoped></style>
