import React, { useImperativeHandle } from 'react';
import * as S from './style';
import Pagination from '../pagination';
import { filterNSortDataSource, setFilterState, getPageInfo } from './helpers';
import { useStore } from 'utils/hooks';
import Header from './memorized/header';
import Summary from './memorized/summary';
import Rows from './memorized/rows';
import { IColumn, ITable } from './types';
import Spinner from '../spinner';
export const Table = function(props: ITable, ref: any) {
    const {
        dataSource = [],
        columns = [],
        pagination = {},
        showPagination = false,
        showHeader = true,
        maxChecked = 100,
        onChange,
        scroll,
        height = 'auto',
        actionHover,
        loading,
        defaultChecked = [],
        rowId,
        noData = '暂无数据',
        ...rest
    } = props;
    const [state, dispatch] = useStore({
        page: 1,
        pageSize: 10,
        rowChecked: [] as any,
        sortKey: '',
        sortOrder: undefined,
    });
    var filteredColumns = columns.filter(Boolean) as IColumn[];
    setFilterState(filteredColumns, state, dispatch);

    const { controlledDataSource, page, pageSize } = getPageInfo(state, pagination);
    let rowData: any[];
    let filtered: any[] = [];
    let checkedIndex: any[] = [];
    if (controlledDataSource) {
        rowData = dataSource;
        rowData.forEach((row, idx) => {
            if (defaultChecked.includes(row[rowId])) {
                checkedIndex.push(idx);
            }
        });
    } else {
        filtered = filterNSortDataSource(filteredColumns, dataSource, state);
        filtered.forEach((row, idx) => {
            if (defaultChecked.includes(row[rowId])) {
                checkedIndex.push(idx);
            }
        });
        rowData = filtered.slice((page - 1) * pageSize, page * pageSize);
    }
    const total = pagination.total || (controlledDataSource ? dataSource.length : filtered.length);
    const totalPage = Math.ceil(total / pageSize) || 1;
    if (state.rowChecked.length !== totalPage) {
        let rowChecked = Array(totalPage)
            .fill(0)
            .map(() => Array(pageSize).fill(false));
        if (rowChecked[page - 1]) {
            if (controlledDataSource) {
                rowChecked[page - 1] = rowChecked[page - 1].map((_, idx) => {
                    return checkedIndex.includes(idx);
                });
            } else {
                rowChecked = rowChecked.map((pageRows, pageIndex) => {
                    const flatIdx = pageIndex * pageSize;
                    pageRows = pageRows.map((row, rowIndex) => {
                        return checkedIndex.includes(flatIdx + rowIndex);
                    });
                    return pageRows;
                });
            }
            dispatch({
                rowChecked,
            });
        }
    }
    const isLocalSource = dataSource.length > pageSize;
    useImperativeHandle(
        ref,
        () => {
            return {
                resetChecked: function() {
                    onChange && onChange({ checked: [] });
                    checkedIndex = [];
                    let rowChecked = Array(totalPage)
                        .fill(0)
                        .map(() => Array(pageSize).fill(false));
                    dispatch({
                        rowChecked,
                    });
                },
            };
        },
        []
    );
    return (
        <div>
            <S.Wrapper height={height} {...rest}>
                <S.TableStyle scroll={scroll}>
                    {showHeader && (
                        <thead>
                            <Header
                                columns={filteredColumns}
                                state={state}
                                dispatch={dispatch}
                                rowData={rowData}
                                tableProps={props}
                            />
                        </thead>
                    )}
                    <tbody>
                        {rowData.length > 0 && <Summary {...props} />}
                        {rowData.length > 0 && (
                            <Rows
                                tableProps={props}
                                rowData={rowData}
                                state={state}
                                dispatch={dispatch}
                                actionHover={actionHover}
                            />
                        )}
                        {rowData.length === 0 && (
                            <tr>
                                <S.NoDataTd>
                                    <S.NoDataWrap>{loading ? <Spinner size={24} /> : noData}</S.NoDataWrap>
                                </S.NoDataTd>
                            </tr>
                        )}
                    </tbody>
                </S.TableStyle>
            </S.Wrapper>
            {showPagination && rowData.length > 0 && (
                <S.PaginationContainer>
                    <Pagination
                        page={page}
                        pageSizeOptions={pagination.pageSizeOptions}
                        showPageSizeOptions={pagination.showPageSizeOptions || false}
                        showJumper={pagination.showJumper || false}
                        pageSize={pageSize}
                        total={total}
                        type="mini"
                        onChange={({ page, pageSize }) => {
                            dispatch({ page, pageSize });
                            onChange &&
                                onChange({ pagination: { page, pageSize }, checked: isLocalSource ? undefined : [] });
                        }}
                    />
                </S.PaginationContainer>
            )}
        </div>
    );
};

export default React.forwardRef(Table);
