import React, {
  createContext,
  forwardRef,
  ReactElement,
  ReactNode,
  useCallback,
} from 'react';
import { VirtualGridRepeaterBase } from './VirtualGridRepeaterBase';
import { VirtualTableRow } from './VirtualTableRow';
import { TableForceRenderIndexes } from './TableForceRenderIndexes';
import { useVirtualGridStateContext } from './VirtualGridStateContext';
import { VirtualTableRowMutated } from './VirtualTableRowMutated';
import { RenderItem } from './RenderItem';

const OuterElementPropsContext = createContext({});

export interface VirtualTableRepeaterProps {
  children: ReactElement[];
}

export function VirtualTableRepeater({ children }: VirtualTableRepeaterProps) {
  const gridState = useVirtualGridStateContext();

  const renderItem = useCallback<RenderItem>(
    (index, { style, itemKey, index2d } = {}) => {
      return (
        <VirtualTableRowMutated
          index={index}
          style={style}
          itemKey={itemKey}
          rowIndex={index2d?.rowIndex}
        >
          {children}
        </VirtualTableRowMutated>
      );
    },
    [children],
  );

  return (
    <VirtualGridRepeaterBase
      innerElementType={TableForceRenderIndexes}
      outerElementType={OuterElement}
      gridState={gridState}
      renderItem={renderItem}
    >
      {VirtualTableRow}
    </VirtualGridRepeaterBase>
  );
}

// wrap with forwardRef to avoid warning in console about ref being passed to a function component without `forwardRef`.
// react-window passes the ref - https://github.com/bvaughn/react-window/blob/6ff5694ac810617515acf74401ba68fe2951133b/src/createGridComponent.js#L464
export const OuterElement = forwardRef(
  ({ children, ...rest }: { children?: ReactNode }, _ref) => {
    return (
      <OuterElementPropsContext.Provider value={rest}>
        {children}
      </OuterElementPropsContext.Provider>
    );
  },
);
