import React from 'react';
import Hook from '../../hook';
import { DataColumnExtra, TableContext, TableMessages } from '../types/table.type';
import { DataRow } from '../types/body.type';
import { DataTableBody } from './body';
import { TableBodyRowHeight } from './style';

interface DataColumn extends DataColumnExtra {
    sticky?: number,
}

export interface DataTableBodyVirtualizedProps {
    tableRef: any,
    context: TableContext,
    messages: TableMessages,
    selectable: boolean,
    onDataChange: (column: DataColumn, row: DataRow, value: any) => void
}

export const DataTableBodyVirtualized: React.FC<DataTableBodyVirtualizedProps> = ({ tableRef, context, messages, selectable, onDataChange }) => {
    const status = React.useRef({ scroll: 0, hold: false })
    const [virtualization, setVirtualization] = React.useState({ from: 0, to: 0 });

    React.useLayoutEffect(() => {
        tableRef.current.scrollTop = status.current.scroll;
        status.current.hold = false;
    })
    Hook.useScrollPosition(tableRef, ({ current }) => {
        if (!status.current.hold) {
            const scroll = current.y;
            const viewportRows = Math.ceil(current.h / TableBodyRowHeight);
            const viewportHeight = viewportRows * TableBodyRowHeight;
            const rowsBuffered = Math.max(2, viewportRows);

            const p = Math.ceil(scroll / TableBodyRowHeight) * TableBodyRowHeight;
            const f = Math.floor(p / TableBodyRowHeight) - rowsBuffered;
            const t = Math.ceil((p + viewportHeight) / TableBodyRowHeight) + rowsBuffered;
            const r = f < 0 ? -f : 0;
            const from = Math.max(0, f);
            const to = Math.min(t + r, 1000);

            status.current.scroll = scroll;
            tableRef.current.scrollTop = status.current.scroll;

            if (virtualization.from !== from || virtualization.to !== to) {
                status.current.hold = true;
                setVirtualization({ from, to });
            }
        }
    }, 100)


    return (
        <DataTableBody
            tableRef={tableRef}
            context={context}
            messages={messages}
            selectable={selectable}
            virtualization={virtualization}
            onDataChange={onDataChange} />
    )
}