import { NestedTableKeyedItem, NestedTableState } from '../../state';
import React, {
  forwardRef,
  MutableRefObject,
  ReactElement,
  useMemo,
} from 'react';
import {
  VirtualTableRepeater,
  VirtualTableRepeaterProps,
} from '../VirtualGridRepeater/VirtualTableRepeater';
import { VirtualGridStateProvider } from '../VirtualGridRepeater/VirtualGridStateContext';
import { NestedTableRow } from './NestedTableRow';
import { useNestedModeColumns } from './useNestedModeColumns';
import { useFlatModeColumns } from './useFlatModeColumns';
import { TableColumn as TableColumnWSR } from '@wix/design-system/dist/types/Table';
import type { NestedTableDragAndDrop } from '../NestedTableDragAndDrop/NestedTableDragAndDrop';
import { NestedTablePlaceholderStatesRow } from './NestedTablePlaceholderStatesRow';

export interface UseModeTableProps<C extends string> {
  state: NestedTableState<C>;
  horizontalScroll?: boolean;
  actionCellWidth?: string | number;
  actionCellProps?: Partial<Omit<TableColumnWSR<any>, 'render' | 'style'>>;
  dragAndDrop?: typeof NestedTableDragAndDrop;
}

export function useModeTableProps<C extends string>(
  props: UseModeTableProps<C>,
) {
  const {
    state: wrapperState,
    horizontalScroll,
    actionCellWidth,
    actionCellProps,
    dragAndDrop,
  } = props;

  const { isFlatMode } = wrapperState;
  const state = isFlatMode ? wrapperState.flat : wrapperState.nested;

  const key = wrapperState.isFlatMode.toString();

  const BodyElementType = useMemo(
    () =>
      ({ children }: VirtualTableRepeaterProps) =>
        (
          <VirtualGridStateProvider key={key} value={state.virtual}>
            <VirtualTableRepeater>{children}</VirtualTableRepeater>
          </VirtualGridStateProvider>
        ),
    [state, key],
  );

  const TrElementType = useMemo(
    () =>
      isFlatMode
        ? undefined
        : forwardRef(
            (
              props: {
                children: ReactElement[];
                rowData: NestedTableKeyedItem<C, any, any>;
                className: string;
              },
              ref:
                | ((instance: HTMLTableRowElement | null) => void)
                | MutableRefObject<HTMLTableRowElement | null>
                | null,
            ) =>
              props.rowData.item.originalKeyedItem ? (
                <NestedTableRow
                  ref={ref}
                  {...props}
                  item={props.rowData.item}
                  dragAndDrop={dragAndDrop}
                />
              ) : (
                <NestedTablePlaceholderStatesRow
                  ref={ref}
                  {...props}
                  item={props.rowData.item}
                />
              ),
          ),
    [isFlatMode, dragAndDrop],
  );

  const nestedColumns = useNestedModeColumns({
    state: wrapperState,
    horizontalScroll,
    actionCellWidth,
    actionCellProps,
    dragAndDrop,
  });

  const flatColumns = useFlatModeColumns({
    state: wrapperState,
    horizontalScroll,
    actionCellWidth,
    actionCellProps,
  });

  return {
    state,
    key,
    BodyElementType,
    TrElementType,
    columns: isFlatMode ? flatColumns : nestedColumns,
  };
}
