import { RootPortal, ScrollView, Text, View } from '@tarojs/components'
import Taro from '@tarojs/taro'
import classnames from 'classnames'
import type { FC } from 'react'
import React, { useCallback, useMemo, useRef, useState } from 'react'
import Iconfont from '../iconfont/iconfont'
import InfiniteScroll from '../infiniteScroll'
import LoadMore, { LoadMoreStatus } from '../LoadMore'
import type { ToolTipRef } from '../toolTips'
import CellTips from './components/CellTips'
import styles from './index.module.scss'

export interface ColumnsType {
  title: string
  dataIndex: string
  width: string
  key: string
  render?: (text?: string, record?: RecordType, index?: number) => React.ReactNode
  ellipsis?: boolean | { isEllipsis: boolean; rows: number }
  showTipsConfig?: {
    tips: string | ((text?: string, record?: RecordType, rowIndex?: number) => string)
    isShowTips: boolean
  }
}

export interface RecordType {
  key: string
  [Property: string]: any
}

export interface TablePropsType {
  columns: ColumnsType[]
  dataSource?: { list: RecordType[]; total: number }
  onLoadMore?: () => void
  height?: number
  moreText?: string
  loadingText?: string
  noMoreText?: string
  emptyText?: string
  safeAreaInsetBottom?: boolean
}
// 生成唯一的cellId
const generateCellId = (row: number, col: number) => {
  return `cell-${row}-${col}`
}
const Table: FC<TablePropsType> = (props) => {
  const { columns, dataSource, onLoadMore, height = 400, moreText = '查看更多', loadingText = '加载中', noMoreText = '没有更多了', emptyText = '暂无数据', safeAreaInsetBottom = true } = props

  const handleShowMore = () => {
    onLoadMore && onLoadMore()
  }

  const getColumnStyle = useCallback((columnConfig: ColumnsType) => {
    const columnStyle = {}
    if (typeof columnConfig.ellipsis === 'boolean' && columnConfig.ellipsis) {
      columnStyle[styles.ellipsis_1] = true
    }
    if (typeof columnConfig.ellipsis === 'object' && columnConfig.ellipsis.isEllipsis) {
      const rows = columnConfig.ellipsis.rows
      if (rows === 2) {
        columnStyle[styles.ellipsis_2] = true
      }
      else {
        columnStyle[styles.ellipsis_1] = true
      }
    }
    return columnStyle
  }, [])

  const loadMoreComponent = useMemo(() => {
    if (dataSource) {
      if (dataSource.list.length === 0 && dataSource.list.length === dataSource.total) {
        return <LoadMore emptyText={emptyText} status="empty"></LoadMore>
      }
      else if (dataSource.list.length < dataSource.total) {
        return <LoadMore moreText={moreText} status="more" onClick={handleShowMore}></LoadMore>
      }
      else if (dataSource.list.length >= dataSource.total) {
        return <LoadMore noMoreText={noMoreText} status="noMore"></LoadMore>
      }
    }
    else {
      return <LoadMore moreText={moreText} loadingText={loadingText} noMoreText={noMoreText} status="loading"></LoadMore>
    }
  }, [dataSource])

  const toolTipsRef = useRef<ToolTipRef>(null)
  // 当前的提示信息
  const currentTips = useRef<{ title: string; tips?: string; width: string }>({ title: '', tips: '', width: '' })
  // 当前的子节点的宽高
  const currentChildrenNode = useRef<{ cellWidth: number; cellHeight: number }>({
    cellWidth: 0,
    cellHeight: 0,
  })
  const [toolTipsStyle, setToolTipsStyle] = useState<React.CSSProperties>({ position: 'fixed' })
  const [, setForceUpdate] = useState({})
  const handleClickCell = (id: string, columnConfig: ColumnsType, rowSource, rowIndex: number) => {
    if (toolTipsRef.current?.visible) {
      toolTipsRef.current?.hide()
    }
    // 提示
    if (typeof columnConfig.showTipsConfig === 'object' && columnConfig.showTipsConfig.isShowTips) {
      currentTips.current = {
        width: columnConfig.width,
        title: rowSource[columnConfig.dataIndex],
        tips: typeof columnConfig.showTipsConfig?.tips === 'function' ? columnConfig.showTipsConfig?.tips(rowSource[columnConfig.dataIndex], rowSource, rowIndex) : columnConfig.showTipsConfig?.tips,
      }
      setForceUpdate({})
      setTimeout(() => {
        const query = Taro.createSelectorQuery()
        query.select(`#${id}`).boundingClientRect()
        query.exec((res) => {
          currentChildrenNode.current = {
            cellWidth: res[0].width,
            cellHeight: res[0].height,
          }
          setToolTipsStyle({
            position: 'fixed',
            top: `${res[0].top}px`,
            left: `${res[0].left}px`,
          })
          toolTipsRef.current?.show()
          console.log('res===》', res)
        })
      }, 100)
    }
  }

  const hiddenChildrenToolTips = useMemo(() => {
    return <Text id="hiddenTips" className={styles.td} style={{ color: 'transparent', width: currentChildrenNode.current.cellWidth, height: currentChildrenNode.current.cellHeight }}>{currentTips.current.title}</Text>
  }, [currentTips.current.title])

  const sourceContainer = () => {
    return (
      <>
        {!!dataSource?.list?.length
          && dataSource.list.map((source, row) => {
            return (
              <View className={classnames(styles.tr, styles['bg-line'])} key={source.key}>
                {columns.map((column, col) => {
                  const cellId = generateCellId(row, col)
                  if (column.render) {
                    return (
                      <View id={cellId} key={col} className={styles.td} style={{ width: column.width }}>
                        {/* 判断表头是不是有render 有就执行render */}
                        {column.render(source[column.dataIndex], source, row)}
                      </View>
                    )
                  }
                  else {
                    return (
                      <View id={cellId} key={col} className={classnames(styles.td, getColumnStyle(column))} style={{ width: column.width }} onClick={() => handleClickCell(cellId, column, source, row)}>
                        {
                          source[column.dataIndex] // 根据表头填数据
                        }
                      </View>
                    )
                  }
                })}
              </View>
            )
          })}
        {loadMoreComponent}
      </>
    )
  }

  return (
    <View className={styles.table}>
      <View className={classnames(styles.tr, styles['bg-header'])}>
        {columns.map((column) => {
          return (
            <View className={styles.th} style={{ width: column.width }} key={column.key}>
              {column.title}
            </View>
          )
        })}
      </View>
      <InfiniteScroll enableLoadMoreStatus={false} safeAreaInsetBottom={safeAreaInsetBottom}>
        {sourceContainer()}
      </InfiniteScroll>
      <CellTips childrenNode={currentChildrenNode.current} ref={toolTipsRef} customContainerStyle={toolTipsStyle} placement="top" content={currentTips.current?.tips}>
        {hiddenChildrenToolTips}
      </CellTips>
    </View>
  )
}
export default Table
