import React, { useMemo, useState } from 'react';
import { runInAction } from 'mobx';
import { FiltersMap, KeyedItem } from '@wix/bex-core';
import { observer } from 'mobx-react-lite';
import { CollectionTable, CollectionTableBaseProps } from '../CollectionTable';
import { useTableSectionRow } from './useTableSectionRow';
import { TableState } from '../../state';
import {
  GroupBy,
  RenderSection,
  SectionEvents,
} from '../CollectionSectionHeader';
import { TableSectionsState } from './TableSectionsState';

export interface TableSectionsProps<T, F extends FiltersMap>
  extends CollectionTableBaseProps<T, F> {
  groupBy: GroupBy<T>;
  renderSection: RenderSection<T>;
  table: TableState<T, F>;
  collapsible?: boolean;
  events?: SectionEvents;
}

const _TableSections = <T, F extends FiltersMap>({
  groupBy,
  renderSection,
  table,
  columns,
  rowDetails,
  collapsible,
  events,
  ...collectionTableProps
}: TableSectionsProps<T, F>) => {
  const [state] = useState(
    () => new TableSectionsState(table, groupBy, renderSection, collapsible),
  );

  runInAction(() => {
    state.renderSection = renderSection;
  });
  state.onToggleCallback = events?.onToggle;

  const columnsWithSections = useMemo(
    () =>
      columns.map((column) => ({
        ...column,
        render: (item: T, rowNum: number) => {
          const keyedItem = state.sectionsKeyedItems[rowNum];
          if (keyedItem && state.isSectionRow(keyedItem)) {
            return null;
          }

          return column.render(item, rowNum);
        },
      })),
    [columns],
  );

  const wrappedRowDetails = useMemo(() => {
    if (!rowDetails) {
      return undefined;
    }
    return (rowData: KeyedItem<T>, rowNum: number) => {
      if (state.isSectionRow(rowData)) {
        return null;
      }
      return rowDetails(rowData, rowNum);
    };
  }, [rowDetails, state]);

  const TableSectionsTrElement = useTableSectionRow(state);

  return (
    <CollectionTable
      {...collectionTableProps}
      rowDetails={wrappedRowDetails}
      state={state.table}
      columns={columnsWithSections}
      keyedItems={state.sectionsKeyedItems}
      TrElementType={TableSectionsTrElement}
      isRowDisabled={(keyedItem) => {
        return state.isSectionRow(keyedItem);
      }}
      isUsingExpandCollapse={collapsible}
    />
  );
};

export const TableSections = observer(_TableSections);

export type TableSectionsProp<T> = {
  TableSections: typeof TableSections;
  groupBy: GroupBy<T>;
  renderSection: RenderSection<T>;
  collapsible?: boolean;
  events?: SectionEvents;
};
