import { VNode } from 'vue'
import { VxeTableInstance } from 'vxe-table'
interface ColumnAttrs {
  field?: string
  title?: string
  width?: string | number
  [key: string]: unknown
}

export interface TableColumn {
  prop: string
  label: string
  attrs?: ColumnAttrs
  render?: {
    edit?: (params: { row: TableRowData }) => VNode | VNode[] | JSX.Element
    default?: (params: { row: TableRowData }) => VNode | VNode[] | JSX.Element
    [key: string]:
      | ((params: { row: TableRowData }) => VNode | VNode[] | JSX.Element)
      | undefined
  }
}

interface TableRowData {
  [key: string]: unknown
}

type SlotFunction = (scope: {
  row: TableRowData
}) => VNode | VNode[] | JSX.Element

export default defineComponent({
  name: 'CustomizeTable',
  props: {
    config: {
      type: Array as PropType<TableColumn[]>,
      default: () => [],
    },
    tableEditConfig: {
      type: Object,
      default: () => ({}),
    },
    modelValue: {
      type: Object,
      default: () => ({}),
    },
    getTablelist: {
      type: Function as PropType<(...args: unknown[]) => Promise<unknown>>,
      default: null,
    },
    isShowCheckBox: {
      type: Boolean,
      default: true,
    },
  },
  emits: ['update:modelValue', 'checkbox-change', 'getCheckboxRecords'],
  setup(props, { emit, attrs }) {
    const tableRef = ref<VxeTableInstance | null>(null)
    const tableData = ref<Record<string, unknown>[]>([])
    const tableColumns = ref<TableColumn[]>([])
    const editConfig = computed(() => {
      return {
        trigger: 'dblclick',
        mode: 'cell',
        enabled: false,
        ...props.tableEditConfig,
      }
    })

    watch(
      () => props.config,
      (val) => {
        if (val?.length) {
          tableColumns.value = val
        }
      },
      {
        immediate: true,
      },
    )
    watch(
      () => props.modelValue,
      (val) => {
        tableData.value = Array.isArray(val) ? val : []
      },
      {
        immediate: true,
      },
    )

    async function getList() {
      if (props.getTablelist) {
        try {
          const data = await props.getTablelist()
          console.log(78, data)
        } catch (error) {
          console.log(error)
        }
      }
    }
    //获取选中数据
    const getSelectEvent = () => {
      const $table = tableRef.value
      if ($table) {
        const selectRecords = $table.getCheckboxRecords()
        emit('getCheckboxRecords', selectRecords)
      }
    }
    //设置高亮行
    const selectRowEvent = (row: TableRowData) => {
      const $table = tableRef.value
      if ($table) {
        $table.setCurrentRow(row)
      }
    }

    onMounted(() => {
      getList()
    })

    return {
      tableRef,
      tableData,
      tableColumns,
      editConfig,
      getSelectEvent,
      selectRowEvent,
      attrs,
    }
  },
  render() {
    return (
      <vxe-table
        ref={(el: VxeTableInstance) => (this.tableRef = el)}
        data={this.tableData}
        height="100%"
        edit-config={this.editConfig}
        onCheckboxChange={this.getSelectEvent}
        onCheckboxAll={this.getSelectEvent}
        {...this.attrs}
      >
        {this.isShowCheckBox && (
          <vxe-column type="checkbox" width="50" align="center"></vxe-column>
        )}

        <vxe-column align="center" type="seq" width="50" title="序号" />
        {this.tableColumns.map((item: TableColumn, index: number) => (
          <vxe-column
            key={index}
            field={item.prop}
            title={item.label}
            {...item.attrs}
          >
            {{
              ...(() => {
                // 创建基础插槽配置
                const slots: Record<string, SlotFunction> = {
                  // 默认的 default 插槽实现
                  default: ({ row }) => <span>{row[item.prop]}</span>,
                }

                if (item.render) {
                  // 添加所有自定义插槽
                  Object.entries(item.render).forEach(
                    ([slotName, renderFn]) => {
                      if (renderFn) {
                        slots[slotName] = (scope: { row: TableRowData }) =>
                          renderFn(scope)
                      }
                    },
                  )
                }

                return slots
              })(),
            }}
          </vxe-column>
        ))}
      </vxe-table>
    )
  },
})
