import { useSize } from "ahooks";
import React, { useRef, useState, useEffect } from "react"
import Table, { BaseTableProps, ColumnShape, SortOrder } from 'react-base-table'
import 'react-base-table/styles.css'
import './index.less'
import { Empty, Pagination, Skeleton, Spin } from "antd";
import { PaginationProps } from "antd/es/pagination";

interface Props extends Omit<BaseTableProps, 'width'> {
    isPagination?: boolean,
    pagination?: PaginationProps
    width?: number
    loading?: boolean
    onChange?: (data: {
        pagination?: { current?: number, pageSize?: number, gzh?: string },
        sortData?: { column: ColumnShape<unknown>, field: React.Key, order: "ascend" | "descend" }
    }) => void
}
const BaseTable: React.FC<Props> = ({ isPagination = true, pagination, width, height, estimatedRowHeight, rowHeight, fixed, columns, loading, onChange, ...props }) => {

    /***************************************/
    const ref = useRef(null);
    const tableRef = useRef(null);
    const size = useSize(ref);
    const [operate, setOperate] = useState<{
        pagination?: { current?: number, pageSize?: number },
        sortData?: { column: ColumnShape<unknown>, key: React.Key, order: SortOrder }
    }>({})
    /***************************************/

    useEffect(() => {
        setOperate({ ...operate, pagination: { current: pagination?.current || 1, pageSize: pagination?.pageSize || pagination?.defaultPageSize || 20 } })
    }, [pagination?.current, pagination?.pageSize, pagination?.defaultPageSize])

    let tableProps: BaseTableProps = {
        fixed: fixed || true,  // 是否开启 列的宽度是固定的还是灵活的
        width: width || size.width || 900,  // 表固定宽度
        height: height || 700,              // 表固定高度
    }
    if (estimatedRowHeight) {
        tableProps.estimatedRowHeight = estimatedRowHeight   // 灵活高度
        tableProps.rowHeight = estimatedRowHeight() || rowHeight || 26
        if (props?.data?.length < 10) {
            tableProps.maxHeight = 700
        }
    } else {
        tableProps.rowHeight = rowHeight || 26               // 固定高度
        if (props?.data?.length < 20) {
            tableProps.maxHeight = 700
        }
    }
    if (props.frozenData?.length > 0 && tableProps.rowHeight && tableProps.height) {
        tableProps.height = tableProps.height + tableProps.rowHeight
    }
    if (tableProps.rowHeight && tableProps.rowHeight < 26) {
        tableProps.rowHeight = 26
    }
    if (columns) {
        let totalWidth = columns.reduce((pre: number, cur: { width: number; }) => {
            pre += cur.width
            return pre
        }, 0)
        if (totalWidth < tableProps.width) {
            let length = columns?.length || 1
            let diffW = (tableProps.width - totalWidth - 6) / length
            tableProps.fixed = false
            columns = columns.map((item: any) => {
                return { ...item, width: item.width + diffW }
            })
        }
    }
    if (!props?.data || props?.data?.length === 0) {
        delete tableProps.maxHeight
        tableProps.height = 200
    }

    tableProps.columns = columns

    tableProps = { ...tableProps, ...props }

    // 排序操作
    const onColumnSort = (sortBy: { column: ColumnShape<unknown>, key: React.Key, order: SortOrder }) => {
        const { key, order } = sortBy;
        let newOperate = JSON.parse(JSON.stringify(operate))
        const sortData = newOperate?.sortData
        if (sortData && sortData.key === key) {
            if (order === 'asc') {
                newOperate = { ...newOperate, sortData: undefined } // 取消排序
            } else {
                newOperate = { ...newOperate, sortData: sortBy }
            }
        } else {
            newOperate = { ...newOperate, sortData: sortBy }
        }
        setOperate(newOperate)
        onChange?.({ ...newOperate, sortData: newOperate?.sortData ? { ...newOperate.sortData, field: newOperate.sortData.key, order: newOperate.sortData.order === 'asc' ? 'ascend' : 'descend' } : undefined })
    }

    // const rowRenderer = ({ isScrolling, cells }: any) => {
    //     if (isScrolling) return <Skeleton.Button active size="small" block />
    //     return cells
    // }

    return <Spin spinning={loading}>
        <div ref={ref}>
            <Table
                ref={tableRef}
                overscanRowCount={3}
                emptyRenderer={<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
                sortBy={operate?.sortData}
                onColumnSort={onColumnSort}
                // useIsScrolling
                // rowRenderer={rowRenderer}
                {...tableProps}
            />
            {isPagination && <div className="pagination">
                <Pagination
                    onChange={(page: number, pageSize: number) => {
                        setOperate({ ...operate, pagination: { current: page, pageSize } });
                        onChange?.({ ...operate, pagination: { current: page, pageSize }, sortData: operate?.sortData ? { ...operate.sortData, field: operate.sortData.key, order: operate.sortData.order === 'asc' ? 'ascend' : 'descend' } : undefined });
                        (tableRef.current as any)?.scrollToTop(0)
                    }}
                    {...pagination}
                />
            </div>}
        </div>
    </Spin>
}

export default React.memo(BaseTable)