import type { Ref } from 'vue';

import type { VxeGridListeners, VxeTableGridOptions } from '#/adapter/vxe-table';

import { watch } from 'vue';

import { useVbenVxeGrid } from '#/adapter/vxe-table';

interface UseCardListGridOptions<RowType, OrderType> {
  payment: Ref<any>;
  selectedData: Ref<OrderType[] | undefined>;
  rowKey: string;
  rowKeyPrefix?: string;
  columns: VxeTableGridOptions<RowType>['columns'];
  query: (params: any) => Promise<any>;
  transformData: (row: RowType[]) => OrderType[];
  emit: (event: 'completeCheck' | 'deletedChecked', payload: any) => void;

  formOptions?: any;
  gridOptions?: Partial<VxeTableGridOptions<RowType>>;
  gridEvents?: VxeGridListeners<RowType>;
}

export function useCardListGrid<RowType, OrderType>(
  options: UseCardListGridOptions<RowType, OrderType>,
) {
  const {
    payment,
    selectedData,
    rowKey,
    rowKeyPrefix,
    columns,
    query,
    transformData,
    emit,
    formOptions,
    gridOptions: userGridOptions,
    gridEvents: userGridEvents,
  } = options;

  function setChecked(data: OrderType[]) {
    const currentPageData = gridApi.grid.getData();
    const rows = currentPageData.filter((row: any) =>
      data.some((item: any) => item.id === row[rowKey]),
    );
    rows.length > 0 && gridApi.grid.setCheckboxRow(rows, true);
  }

  function cancelCheck(id: number) {
    gridApi.grid.setCheckboxRow({ [rowKey]: id }, false);
  }

  const defaultGridOptions: VxeTableGridOptions<RowType> = {
    columns,
    exportConfig: {},
    height: 'auto',
    keepSource: true,
    rowConfig: {
      keyField: rowKey,
      isHover: true,
    },
    checkboxConfig: {
      reserve: true,
      showReserveStatus: true,
      highlight: true,
      trigger: 'row',
    },
    pagerConfig: {
      enabled: true,
    },
    proxyConfig: {
      response: {
        result: 'records',
        total: 'total',
        list: 'records',
      },
      ajax: {
        query: async ({ page }, formValues) => {
          const data = await query({
            page: page.currentPage,
            limit: page.pageSize,
            ...formValues,
          });
          // 确保 listKey 是字符串类型
          const responseList = userGridOptions?.proxyConfig?.response?.list;
          const listKey = typeof responseList === 'string' ? responseList : 'records';
          const list = data[listKey].map((item: any) => ({
            ...item,
            [rowKey]: `${rowKeyPrefix || ''}${item[rowKey]}`,
          }));
          data[listKey] = list;
          return data;
        },
        querySuccess: () => {
          setChecked(selectedData.value || []);
        },
      },
    },
  };

  const finalGridOptions: VxeTableGridOptions<RowType> = {
    ...defaultGridOptions,
    ...userGridOptions,
    // 对 proxyConfig 进行特殊处理，确保用户配置能覆盖默认配置
    proxyConfig: {
      ...defaultGridOptions.proxyConfig,
      ...userGridOptions?.proxyConfig,
      // 对 proxyConfig.ajax 进行特殊处理
      ajax: {
        ...defaultGridOptions.proxyConfig?.ajax,
        ...userGridOptions?.proxyConfig?.ajax,
      },
      // 对 proxyConfig.response 进行特殊处理
      response: {
        ...defaultGridOptions.proxyConfig?.response,
        ...userGridOptions?.proxyConfig?.response,
      },
    },
  };

  const defaultGridEvents: VxeGridListeners<RowType> = {
    checkboxChange: ({ checked, row }: any) => {
      checked ? emit('completeCheck', transformData([row])) : emit('deletedChecked', [row[rowKey]]);
    },
    checkboxAll: ({ checked }: any) => {
      const rows = gridApi.grid.getData();
      const ids = rows.map((item: any) => item[rowKey]);
      checked ? emit('completeCheck', transformData(rows)) : emit('deletedChecked', ids);
    },
  };

  const finalGridEvents: VxeGridListeners<RowType> = {
    ...defaultGridEvents,
    ...userGridEvents,
  };

  const [Grid, gridApi] = useVbenVxeGrid({
    formOptions,
    gridOptions: finalGridOptions as any,
    gridEvents: finalGridEvents,
  });

  watch(
    payment,
    (newPayment, oldPayment) => {
      if (newPayment?.id && newPayment.id !== oldPayment?.id) {
        gridApi?.reload();
      }
    },
    { immediate: false },
  );

  return {
    Grid,
    gridApi,
    cancelCheck,
    setChecked,
  };
}
