import React, { useEffect } from 'react';
import { FiltersMap } from '@wix/bex-core';
import { Grid, GridBasePropsWithoutPreset } from '../Grid';
import { Table, TableProps } from '..';
import { observer } from 'mobx-react-lite';
import type { TableGridSwitchState } from '../../state/TableGridSwitchState';
import { TableGridSwitchButton } from '../TableGridSwitchButton';
import { GridPresetProps } from '../Grid/Grid.types';
import type { TableGridSwitchDragAndDrop } from './TableGridSwitchDragAndDrop';
import { InitialLoader } from '../InitialLoader';
import { GridSectionsContent } from '../GridSections/GridSectionsContent';
import type { Section } from '../CollectionSectionHeader';
import { TableSections } from '../TableSections';

export interface TableGridSwitchBaseProps<T, F extends FiltersMap>
  extends Omit<
      GridBasePropsWithoutPreset<T, F>,
      'state' | 'dragAndDrop' | 'tableGridSwitchButton' | 'sticky' | 'sections'
    >,
    Omit<
      TableProps<T, F>,
      'state' | 'dragAndDrop' | 'tableGridSwitchButton' | 'sticky' | 'sections'
    > {
  /**
   * A `TableGridSwitchState` instance created using [useTableGridSwitch](./?path=/story/base-components-collections-tablegridswitch-usetablegridswitchcollection--usetablegridswitchcollection).
   */
  state: TableGridSwitchState<T, F>;
  /**
   * Adds functionality to allow visitors to reorder items manually.
   * For more information, see the [Drag and Drop Overview](./?path=/story/features-sort-drag-and-drop--overview).
   * @overrideType [TableGridSwitchDragAndDrop](./?path=/story/features-sort-drag-and-drop--tablegridswitchdraganddrop)
   * @external
   */
  dragAndDrop?: typeof TableGridSwitchDragAndDrop;
  /**
   * Configuration for rendering sections. When provided, the component will render with section headers
   * that group related rows together for both Grid and Table views.
   * @external
   */
  sections?: {
    GridSections: typeof GridSectionsContent;
    TableSections: typeof TableSections;
    renderSection: (item: T) => Section;
  };
}

export type TableGridSwitchProps<T, F extends FiltersMap> = GridPresetProps<
  T,
  TableGridSwitchBaseProps<T, F>
>;

export function _TableGridSwitch<T, F extends FiltersMap = FiltersMap>(
  props: TableGridSwitchProps<T, F>,
) {
  const { state, dragAndDrop, sections, ...restProps } = props;
  const { gridState, tableState, toolbar } = state;

  const tableGridSwitchButton = (
    <TableGridSwitchButton state={state.viewTypeState} />
  );

  useEffect(() => state.init(), []);

  const {
    initTask: { status },
  } = state;

  const isLoading = status.isIdle || status.isLoading;

  const gridSections = sections
    ? {
        GridSections: sections.GridSections,
        renderSection: sections.renderSection,
      }
    : undefined;

  const tableSections = sections
    ? {
        TableSections: sections.TableSections,
        renderSection: sections.renderSection,
      }
    : undefined;

  return (
    <>
      {isLoading ? (
        <InitialLoader dataHook="initial-loader" state={toolbar} />
      ) : state.viewType === 'grid' ? (
        <Grid
          {...restProps}
          tableGridSwitchButton={tableGridSwitchButton}
          state={gridState}
          dragAndDrop={dragAndDrop?.grid}
          sections={gridSections}
        />
      ) : (
        <Table
          {...restProps}
          sticky
          tableGridSwitchButton={tableGridSwitchButton}
          state={tableState}
          dragAndDrop={dragAndDrop?.table}
          sections={tableSections}
        />
      )}
    </>
  );
}

export const TableGridSwitch = observer(_TableGridSwitch);
