import { CustomColumnsState } from '../../state';
import { FiltersMap } from '@wix/bex-core';
import { observer } from 'mobx-react-lite';
import React, { useCallback, useEffect } from 'react';
import { Column } from '../../model';
import { Box } from '@wix/design-system';
import { addEventListener } from '@wix/bex-core/util';
import { ColumnListTableListItem } from './ColumnListTableListItem';

export interface ColumnsListProps<T, F extends FiltersMap> {
  state: CustomColumnsState<T, F>;
}

function _ColumnsList<T, F extends FiltersMap>(props: ColumnsListProps<T, F>) {
  const { state } = props;
  const { columnsCollection, dragAndDrop } = state;
  const hasSearchValue = state.searchValue.trim().length > 0;

  useEffect(() => {
    if (dragAndDrop == null) {
      return;
    }
    const {
      table: { sidePanel },
    } = state;

    const disposers = [
      addEventListener(sidePanel.transition.events, 'entered', () => {
        dragAndDrop.listRect._syncThrottled();
      }),
      dragAndDrop.listRect.init(),
    ];

    return () => {
      disposers.forEach((d) => d?.());
    };
  }, []);

  const renderItem = useCallback(
    (column: Column, index: number, { length }: { length: number }) => {
      const itemContent = (
        <ColumnListTableListItem
          key={column.id}
          index={index}
          state={state}
          column={column}
          showDivider={index < length - 1}
        />
      );

      if (dragAndDrop && !hasSearchValue) {
        const { DraggableListItem } = dragAndDrop.components;

        return (
          <DraggableListItem
            key={column.id}
            dndDisabled={column.reorderDisabled}
            id={column.id}
            index={index}
            state={dragAndDrop}
          >
            {itemContent}
          </DraggableListItem>
        );
      }

      return itemContent;
    },
    [hasSearchValue],
  );

  let child = (
    <Box
      direction="vertical"
      dataHook="custom-columns-list"
      backgroundColor="D60"
    >
      {columnsCollection.result.items.map(renderItem)}
    </Box>
  );

  if (dragAndDrop && !hasSearchValue) {
    const { ListDragAndDropContext, DraggableListItemOverlay } =
      dragAndDrop.components;

    child = (
      <ListDragAndDropContext
        state={dragAndDrop}
        onSubmit={async ({ from, over }) => {
          state.customizeColumnsInSidePanelBi({ actionName: 'reorder' });

          state.dragAndDrop?._onCustomColumnsReorder(
            from.item.id,
            over.item.id,
          );
        }}
      >
        <>
          {child}
          <DraggableListItemOverlay
            state={dragAndDrop}
            renderItem={(index) => {
              const item = columnsCollection.result.items[index];
              return item ? renderItem(item, index, { length: 0 }) : null;
            }}
          />
        </>
      </ListDragAndDropContext>
    );
  }

  return child;
}

export const ColumnsList = observer(_ColumnsList);
