<script lang="tsx">
import { computed, defineComponent, onMounted, reactive, ref, toRaw, unref } from 'vue';
import { useAppStore } from '@/store/modules/app';
import { defaultTransform, useNaivePaginatedTable, useTableOperate } from '@/hooks/common/table';
import { useForm } from '../Form/hooks/useForm';
import type { FormProps } from '../Form/types/form';
import type { TableMethods } from './hooks/useTable';
import type { tableProp } from './types';
import { basicProps } from './props';

export default defineComponent({
  name: 'ZTable',
  props: {
    ...basicProps
  },
  emits: ['register', 'add', 'delete'],
  setup(props, { emit, slots }) {
    const appStore = useAppStore();
    const pageSize = import.meta.env.VITE_PAGE_SIZE;
    const propsData = toRaw(props);
    const searchProps = ref<FormProps>();
    const tableProps = ref<tableProp>();
    const commonKeyData = ref();
    const getFormSearch = computed(() => {
      return {
        labelWidth: 120,
        layout: 'horizontal',
        gridProps: {
          cols: '1 xl:4 s:1 l:3',
          itemResponsive: true
        },
        collapsedRows: 1,
        ...unref(searchProps)
      };
    });
    const getTableProps = computed(() => {
      return {
        ...propsData.tableConfig,
        ...unref(tableProps)
      };
    });
    const NTableProps = computed(() => {
      return {
        ...unref(tableProps)
      };
    });
    const [registerSearchForm, { getFieldsValue: getSeachForm, setFormProps: setSearchProps, setFieldsValue }] =
      useForm(getFormSearch.value);
    const searchPage = reactive({
      pageNum: 1,
      pageSize: 10
    });
    const getForm = ref();
    const { columns, columnChecks, data, getData, loading, mobilePagination, getDataByPage } = useNaivePaginatedTable({
      api: () => propsData.api({ ...searchPage, ...getForm.value, ...propsData.defaultParams }),
      transform: response => defaultTransform(response),
      onPaginationParamsChange: params => {
        searchPage.pageNum = Number(params.page);
        searchPage.pageSize = Number(params.pageSize);
      },
      immediate: propsData.immediate,
      paginationProps: {
        pageSizes: pageSize.split(',').map(Number)
      },
      columns: () => handleGetColumns()
    });
    const { checkedRowKeys } = useTableOperate(data, getTableProps.value.keyField, getData);
    function handleGetColumns() {
      const columnsData = [...propsData.columns];
      if (propsData.showTableAction) {
        columnsData.push({
          key: 'operate',
          title: '操作',
          align: 'center',
          width: getTableProps.value.opWdith,
          fixed: 'right',
          render: row => <div class="flex-center gap-8px">{slots.op ? slots.op({ row }) : ''}</div>
        });
      }
      return columnsData;
    }
    function setTableConfig(config: tableProp) {
      tableProps.value = config;
    }
    function getTableCheckedRowKeys() {
      return checkedRowKeys.value;
    }
    function getTableData() {
      return data.value;
    }
    const getTableLoding = computed(() => loading.value);
    const handleCommonTime = (form: Recordable) => {
      const fieldMapToTime = getTableProps.value.fieldMapToTime;

      if (!Array.isArray(fieldMapToTime)) {
        return form;
      }
      fieldMapToTime.forEach(mapping => {
        const [source, target] = mapping;
        const formTimeKey = Array.isArray(source) ? source[0] : source;

        let endTimeKey;
        let startTimeKey;
        if (Array.isArray(target)) {
          if (typeof target[0] === 'string' && typeof target[1] === 'string') {
            [startTimeKey, endTimeKey] = target;
          } else if (Array.isArray(target[1])) {
            [startTimeKey, endTimeKey] = target[1];
          }
        }

        if (formTimeKey && startTimeKey && endTimeKey && form[formTimeKey]) {
          [form[startTimeKey], form[endTimeKey]] = form[formTimeKey];
          Reflect.deleteProperty(form, formTimeKey);
        }
      });
      return form as Recordable;
    };
    const TableMethod: TableMethods = {
      refresh: fetchSearchData,
      setSearchProps,
      setTableLoading,
      setTableConfig,
      getTableCheckedRowKeys,
      getTableData,
      getSeachForm: () => handleCommonTime(getSeachForm()),
      setFieldsValue,
      getTableLoding
    };
    function setTableLoading(flage: boolean) {
      loading.value = flage;
    }
    onMounted(() => {
      emit('register', TableMethod);
    });
    function handleAdd() {
      emit('add');
    }
    function handleDelete() {
      emit('delete', checkedRowKeys.value);
    }
    async function handleReset() {
      getForm.value = getSeachForm();
      if (getTableProps.value.defaultParamsNotReset) {
        const keySearch = getTableProps.value.defaultParamsNotReset;
        getForm.value[keySearch] = commonKeyData.value;
        await setFieldsValue({ [`${keySearch}`]: commonKeyData.value });
      }

      getData();
    }
    async function fetchSearchData() {
      handleSearch();
    }

    function handleSearch() {
      const form = handleCommonTime(getSeachForm());
      console.log(propsData.defaultParams, 'propsData.defaultParams');

      // 查询默认值，重置的时候不重置这个参数
      if (getTableProps.value.defaultParamsNotReset) {
        commonKeyData.value = form[getTableProps.value.defaultParamsNotReset];
      }
      console.log(form, '查询请求参数');

      getForm.value = form;
      getDataByPage(1);
    }
    return {
      registerSearchForm,
      handleDelete,
      checkedRowKeys,
      appStore,
      loading,
      mobilePagination,
      data,
      columns,
      tableProps,
      columnChecks,
      getTableProps,
      handleAdd,
      getData,
      handleReset,
      handleSearch,
      NTableProps
    };
  }
});
</script>

<template>
  <NCard v-if="getTableProps.showSearch" :bordered="false" size="small" class="card-wrapper">
    <NCollapse display-directive="show" :default-expanded-names="['search']">
      <NCollapseItem title="搜索" name="search" display-directive="show">
        <BasicForm @register-form="registerSearchForm" @submit="handleSearch" @reset="handleReset" />
      </NCollapseItem>
    </NCollapse>
  </NCard>
  <NCard :bordered="false" :title="getTableProps.title" size="small" class="card-wrapper sm:flex-1-hidden">
    <template #header-extra>
      <TableHeaderOperation
        v-if="getTableProps.showTableHeaderAction"
        v-model:columns="columnChecks"
        :disabled-delete="checkedRowKeys.length === 0"
        :loading="loading"
        :is-add="getTableProps.showAddButton"
        :is-delete="getTableProps.showDeleteButton"
        @add="handleAdd"
        @delete="handleDelete"
        @refresh="getData"
      >
        <template #prefix>
          <slot name="prefix" :loading="loading"></slot>
        </template>
      </TableHeaderOperation>
    </template>
    <template #header>
      <slot name="header" :loading="loading"></slot>
    </template>
    <NDataTable
      v-bind="NTableProps"
      v-model:checked-row-keys="checkedRowKeys"
      :columns="columns"
      :data="data"
      size="small"
      :flex-height="!appStore.isMobile"
      :scroll-x="getTableProps.scrollX"
      :loading="loading"
      remote
      :row-key="row => row[getTableProps.keyField]"
      :pagination="mobilePagination"
      class="sm:h-full"
    />
  </NCard>
</template>

<style scoped></style>
