import React, { useCallback, useEffect, useMemo, useState } from 'react'
import styles from './index.module.scss'
import { DatePicker, Input, Table } from 'antd'
import ImageLazy from '../ImageLazy'
import classNames from 'classnames'
import { resJiLianFu } from '@/utils/history'

type Props = {
  yHeight?: number //设置表格的高度
  list: any //表格数据
  columnsTemp: any[][] //表格展示
  total?: number //总数
  pageNum?: number
  pageSize?: number
  pagingInfo?: any | boolean
  onChange?: (pageNum: number, pageSize: number) => void
  lastBtn?: any //后面的操作按钮
  startBtn?: any
  classKey?: string //一个组件多次使用的时候要传递，分别设置style
  // 表格简单的合并
  merge?: { type: string; num: number; loc: 'rowSpan' | 'colSpan' }
  // 定制化表头
  myTitle?: { name: string; Com: React.ReactNode }
  // 为空的定制字段
  isNull?: string
  // 设置宽度
  widthSet?: any
  rowKey?: string
}

function MyTable({
  yHeight,
  list,
  columnsTemp,
  total,
  pageNum = 1,
  pageSize = 10,
  pagingInfo = {
    showQuickJumper: true,
    position: ['bottomCenter'],
    showSizeChanger: true
  },
  onChange,
  lastBtn = [],
  startBtn = [],
  classKey = '',
  merge,
  myTitle,
  isNull = '（空）',
  widthSet,
  rowKey = 'id'
}: Props) {
  // 点击操作高亮
  const [clickAc, setClickAc] = useState(0)

  // 表格内容定制化
  const tableComObj = useCallback(
    (key: string, val: string[], id?: any, backFu?: (id: number) => void) => {
      const obj = {
        // 超链接打开
        A: (
          <a href={val[1]} target='_blank' title={val[1]} rel='noreferrer'>
            {val[0]}
          </a>
        ),
        // 点击触发事件
        S: (
          <span
            className={classNames('MTclick', clickAc === id ? 'MTclickAc' : '')}
            onClick={() => {
              if (id && backFu) {
                backFu(id)
                setClickAc(id)
              }
            }}
          >
            {val[1]}
          </span>
        )
      }
      return Reflect.get(obj, key)
    },
    [clickAc]
  )

  useEffect(() => {
    const dom = document.querySelector(`.MyTable${classKey} .ant-table-body`) as HTMLDivElement

    if (dom && yHeight) dom.style.height = yHeight + 'px'
  }, [classKey, yHeight])

  // 页码变化
  const paginationChange = useCallback(
    () => (pageNum: number, pageSize: number) => {
      if (onChange) {
        onChange(pageNum, pageSize)
      }
    },
    [onChange]
  )

  const dataChangeFu = useCallback(
    (v: any) => {
      /**
       * index:序号
       * txt:正常数据
       * img:图片
       * txtChange:判断显示不同字段
       * text:文字比较多的情况
       */

      const obj = {
        index: (_: any, __: any, index: number) => index + 1 + (pageNum - 1) * pageSize,
        txt: (item: any) =>
          v[3] && !item[v[2]] ? (
            <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
          ) : (
            item[v[2]] || isNull
          ),
        // 多个字段拼接
        ping: (item: any) => item[v[2]] + resJiLianFu(item[v[3]]) || isNull,
        // 这个模块特有的级联控制
        txtC: (item: any) =>
          v[1] === '年代' && item[v[2]] === '其他' ? '其他' : resJiLianFu(item[v[2]]),
        // 尺寸
        size: (item: any) => {
          let danWei = resJiLianFu(item.sizeUnit, ' ')

          let txt1 = item.sizeL ? `通长${item.sizeL}` : ''
          let txt2 = item.sizeW ? `通宽${item.sizeW}` : ''
          let txt3 = item.sizeH ? `通高${item.sizeH}` : ''

          txt1 = txt1 ? txt1 + danWei : ''
          txt2 = txt2 ? txt2 + danWei : ''
          txt3 = txt3 ? txt3 + danWei : ''

          let arr = [txt1, txt2, txt3]
          arr = arr.filter(v => v)

          if (!txt1 && !txt2 && !txt3) return '（空）'
          else return arr.join(' - ')
        },
        img: (item: any) =>
          v[3] && !item[v[2]] ? (
            <div dangerouslySetInnerHTML={{ __html: v[3] }}></div>
          ) : (
            <div className='tableImgAuto'>
              <ImageLazy
                width={60}
                height={60}
                srcBig={item.thumbPc || item.filePath}
                src={item[v[2]] || item.thumb}
                offline={(item[v[2]] || item.thumb).includes('http')}
              />
            </div>
          ),
        txtChange: (item: any) => Reflect.get(v[3], item[v[2]]) || v[4] || isNull,
        text: (item: any) => {
          let tempCom: any = item[v[2]] || isNull

          if (tempCom.length >= v[3]) {
            tempCom = tempCom.substring(0, v[3]) + '...'
          }

          if (v[4]) {
            tempCom = tableComObj(v[4], [tempCom, item[v[2]]], item.id, v[5])
          } else if ((item[v[2]] || '').length >= v[3]) {
            tempCom = (
              <span style={{ cursor: 'pointer' }} title={item[v[2]]}>
                {tempCom}
              </span>
            )
          }

          return tempCom
        },
        input: (item: any) => {
          return (
            <Input
              allowClear
              value={item[v[2]]}
              maxLength={v[3]?.maxLength}
              placeholder={v[3]?.placeholder || '请输入'}
              // @ts-ignore
              onInput={v => (item[v[2]] = v.target.value)}
            />
          )
        },
        datePicker: (item: any) => {
          return (
            // @ts-ignore
            <DatePicker onChange={v => (item[v[2]] = v)} />
          )
        }
      }

      return Reflect.get(obj, v[0])
    },
    [isNull, pageNum, pageSize, tableComObj]
  )

  const columns = useMemo(() => {
    const arr: any = columnsTemp.map((v: any) => ({
      title: myTitle && v.includes(myTitle.name) ? myTitle.Com : v[1],
      render: dataChangeFu(v),
      width: widthSet && Reflect.get(widthSet, v[2]) ? Reflect.get(widthSet, v[2]) : 'auto',
      onCell:
        merge && v.includes(merge.type)
          ? // {rowSpan:3}
            (item: any, index: number) => ({
              rowSpan: index === 0 ? merge.num : 0
            })
          : ''
    }))

    return arr
  }, [columnsTemp, dataChangeFu, merge, myTitle, widthSet])

  return (
    <Table
      className={`${styles.MyTable} MyTable${classKey}`}
      scroll={{ y: yHeight ? yHeight : '' }}
      dataSource={list}
      columns={[...startBtn, ...columns, ...lastBtn]}
      rowKey={rowKey}
      pagination={
        pagingInfo
          ? {
              ...pagingInfo,
              current: pageNum,
              pageSize: pageSize,
              total: total,
              onChange: paginationChange()
            }
          : false
      }
    />
  )
}

const MemoMyTable = React.memo(MyTable)

export default MemoMyTable
