import { ref, computed, watch, nextTick, unref } from 'vue'
import { isDefine } from '@/utils/common'

import type { Ref, ShallowRef, UnwrapRef } from 'vue'
import type { InstanceTable } from 'global-type'
import type { MultipleResult } from '@/api/api'

type ArrayObjectType = Array<Record<string, any>>

type MultipleResultType<T = Record<string, any>> = MultipleResult<T>

type InputDataType = MultipleResultType | ArrayObjectType

type TableDataType<T> = Ref<T> | ShallowRef<T>

type ArrayData<T extends InputDataType> = T extends MultipleResultType<infer D> ? D : ExtractArrayValue<T>

type RowType<T extends TableDataType<InputDataType>> = ArrayData<UnwrapRef<T>> & {
  index: number
}

function isMultipleData(data: any): data is MultipleResultType {
  return isDefine(data?.result) && isDefine(data?.totalCount)
}

const useTableCheck = <T extends TableDataType<InputDataType>>(data: T, auto = true) => {
  const tableRef = ref<InstanceTable>()

  const elTableRef = computed(() => {
    return tableRef?.value?.tableRef
  })

  const tableData = computed(() => {
    const d = unref(data)
    let result: RowType<T>[] = []
    if (d) {
      if (isMultipleData(d)) {
        result = d?.result?.map((d, index) => ({ ...d, index: d.index ?? index })) as RowType<T>[]
      } else {
        result = d?.map((d, index) => ({ ...d, index: d.index ?? index })) as RowType<T>[]
      }
    }
    return result
  })

  const current = ref<RowType<T>>()

  const currentView = ref<RowType<T>>()

  const visibleHistory = ref<boolean>(false)

  watch(
    tableData,
    () => {
      current.value = void 0
      currentView.value = void 0
      if (tableData?.value?.length && auto) {
        nextTick(() => {
          elTableRef?.value?.setCurrentRow(tableData.value[0])
        })
      }
    },
    { immediate: true }
  )

  /** 表格选中 */
  const onCurrentChange = (row: RowType<T>) => {
    current.value = row
  }

  /** 表格行双击 */
  const onDbClick = (row: RowType<T>) => {
    currentView.value = row
    visibleHistory.value = true
  }

  /** 下一份 */
  const next = () => {
    elTableRef?.value?.setCurrentRow(tableData.value[((current.value?.index || 0) + 1) % tableData.value.length])
  }

  return {
    tableRef,
    elTableRef,
    tableData,
    current,
    currentView,
    visibleHistory,
    onCurrentChange,
    onDbClick,
    next,
  }
}

export default useTableCheck
