import { useElementBounding } from '@vueuse/core'
import RPC from '@/utils/rpc'

const isFunction = (val) => typeof val === 'function'

export function useTable({
  queryParams = {},
  remoteDataFn,
  onTransformParams,
  onTransformData,
  deleteConfig,
  exportUrl,
  exportFileName,
  searchFormRef,
}) {
  const tableData = ref([])
  const loading = ref(false)
  const total = ref(0)
  /**
   * @type {import('vue').Ref<import('element-plus').TableInstance | null>} tableRef - 表格组件引用
   */
  const tableRef = ref(null)

  /**
   * @type {()=>import('element-plus').FormInstance | null} searchFormRef - 查询表单组件引用
   */
  const _searchFormRef = searchFormRef ? computed(() => searchFormRef()) : ref(null)

  const _queryParams = ref({
    pageNum: 1,
    pageSize: 10,
    ...queryParams,
  })

  const isShowDialog = ref(false)

  function getList() {
    loading.value = true
    const params = onTransformParams?.(_queryParams.value) || _queryParams.value
    remoteDataFn(params)
      .then((response) => {
        const data = onTransformData?.(response) || response
        tableData.value = data?.rows || []
        total.value = data.total
        loading.value = false
      })
      .catch((err) => {
        loading.value = false
        console.error(err)
      })
  }

  /** 搜索按钮操作 */
  function handleQuery() {
    _queryParams.value.pageNum = 1
    getList()
  }
  /** 重置按钮操作 */
  function resetQuery() {
    _searchFormRef.value.resetFields()
    _queryParams.value.pageNum = 1
    getList()
  }

  /** 导出 */
  function handleExport() {
    const params = onTransformParams?.(_queryParams.value) || _queryParams.value
    download(exportUrl, params, exportFileName)
  }

  /** 删除按钮操作 */
  function handleDelete(row) {
    const { remote, message, onSuccess, onError } = deleteConfig
    ElMessageBox.confirm(isFunction(message) ? message(row) : message, '提醒', {
      type: 'warning',
    })
      .then(() => {
        remote(row.id)
          .then(() => {
            getList()
            onSuccess?.()
            ElMessage.success('删除成功')
          })
          .catch((e) => {
            console.error(`删除失败：${e}`)
          })
      })
      .catch(() => {
        onError?.()
      })
  }

  const { tableContainerEl, maxHeight } = useTableMaxHeight()

  return {
    tableData,
    loading,
    total,
    tableRef,
    searchFormRef: _searchFormRef,
    isShowDialog,
    queryParams: _queryParams,
    /** 表格容器 ref */
    tableContainerEl,
    /** 表格自适应外层容器高度 :max-height="maxHeight" */
    maxHeight,

    getList,
    handleQuery,
    resetQuery,
    handleDelete,
    handleExport,
  }
}

export function useTableRPC({
  queryParams = {},
  remoteDataFn,
  onTransformParams,
  onTransformData,
  deleteConfig,
  exportUrl,
  exportFileName,
  searchFormRef,
}) {
  const tableData = ref([])
  const loading = ref(false)
  const total = ref(0)
  /**
   * @type {import('vue').Ref<import('element-plus').TableInstance | null>} tableRef - 表格组件引用
   */
  const tableRef = ref(null)

  /**
   * @type {()=>import('element-plus').FormInstance | null} searchFormRef - 查询表单组件引用
   */
  const _searchFormRef = searchFormRef ? computed(() => searchFormRef()) : ref(null)

  const _queryParams = ref({
    page: 1,
    limit: 10,
    ...queryParams,
  })

  const isShowDialog = ref(false)

  const transformParams = (params) => {
    const _params = {
      page: params.page,
      limit: params.limit,
      orderby: params.orderby || null,
      like: {},
    }
    for (const k in params) {
      if (params[k] && k !== 'page' && k !== 'limit' && k !== 'orderby') {
        _params.like[k] = [`%${params[k]}%`]
      }
    }
    return _params
  }

  function getList() {
    loading.value = true
    const params = transformParams(_queryParams.value)
    RPC.post(remoteDataFn, params)
      .then((response) => {
        tableData.value = response?.rows || []
        total.value = response.count
      })
      .finally(() => {
        loading.value = false
      })
  }

  /** 搜索按钮操作 */
  function handleQuery() {
    _queryParams.value.page = 1
    getList()
  }
  /** 重置按钮操作 */
  function resetQuery() {
    _searchFormRef.value.resetFields()
    _queryParams.value.page = 1
    getList()
  }

  /** 导出 */
  function handleExport() {
    const params = onTransformParams?.(_queryParams.value) || _queryParams.value
    download(exportUrl, params, exportFileName)
  }

  /** 删除按钮操作 */
  function handleDelete(row) {
    const { remote, message, onSuccess, onError, key } = deleteConfig
    ElMessageBox.confirm(isFunction(message) ? message(row) : message, '提醒', {
      type: 'warning',
    })
      .then(() => {
        RPC.post(remote, { id: row[key] })
          .then(() => {
            getList()
            onSuccess?.()
            ElMessage.success('删除成功')
          })
          .catch((e) => {
            console.error(`删除失败：${e}`)
          })
      })
      .catch(() => {
        onError?.()
      })
  }

  const { tableContainerEl, maxHeight } = useTableMaxHeight()

  return {
    tableData,
    loading,
    total,
    tableRef,
    searchFormRef: _searchFormRef,
    isShowDialog,
    queryParams: _queryParams,
    /** 表格容器 ref */
    tableContainerEl,
    /** 表格自适应外层容器高度 :max-height="maxHeight" */
    maxHeight,

    getList,
    handleQuery,
    resetQuery,
    handleDelete,
    handleExport,
  }
}

export function useTableMaxHeight() {
  const tableContainerEl = ref(null)
  const { height } = useElementBounding(tableContainerEl)

  const maxHeight = computed(() => {
    return Number.isNaN(height.value) ? `100%` : Math.floor(height.value)
  })

  return {
    tableContainerEl,
    maxHeight,
  }
}
