import { FiltersMap } from '@wix/bex-core';
import React, { useEffect, useState } from 'react';
import { CollectionTableProps } from './CollectionTable';
import { useToolbarCollectionSyncProps } from '../ToolbarCollection/useToolbarCollectionSyncProps';
import { assertComponentType } from '../assertComponentType';
import {
  CheckboxTooltipContentProp,
  SelectionDisabledProp,
} from '../../state/BulkActionToolbarState';
import { useColumnsSyncProps } from '../../hooks/useColumnsSyncProps';
import { DataExtensionProps, DataExtensionType } from '../DataExtension';
import { isValidElement } from '../isValidElement';

export function useTableCollectionSyncProps<T, F extends FiltersMap>(
  props: CollectionTableProps<T, F> & {
    isUsingTableVirtualization: boolean;
    isUsingExpandCollapse?: boolean;
  },
) {
  const {
    state: table,
    customColumns,
    columns: tableColumns,
    showSelection,
    actionCell,
    multiLevelSorting,
    views,
    selectionDisabled,
    checkboxTooltipContent,
    dataExtension,
    fieldsSource,
    isUsingTableVirtualization,
    isUsingExpandCollapse,
    dragAndDropReorderModeToolbar,
  } = props;

  assertComponentType(customColumns, 'CustomColumns', 'customColumns');
  assertComponentType(
    multiLevelSorting,
    'MultiLevelSorting',
    'multiLevelSorting',
  );
  assertComponentType(views, 'CollectionViewsDropdown', 'views');
  assertComponentType(
    dragAndDropReorderModeToolbar,
    'ReorderModeToolbar',
    'dragAndDropReorderModeToolbar',
  );

  const state = table.toolbar;

  useToolbarCollectionSyncProps({
    ...props,
    state,
    isUsingDragAndDrop: !!props.dragAndDrop,
    isUsingBulkActionsToolbar: !!props.bulkActionToolbar,
    isUsingHorizontalScroll: props.horizontalScroll ?? false,
    isUsingFolders: false,
    isUsingTableVirtualization,
    isUsingExpandCollapse,
  });

  // Attach the field source first, so the custom-columns button it declares is
  // available to useColumnsSyncProps below.
  useState(() => {
    if (isValidElement<DataExtensionProps, DataExtensionType>(dataExtension)) {
      dataExtension.type.setDataExtensionOnTable(state, dataExtension.props);
    } else {
      dataExtension?.setDataExtensionOnTable(state);
    }
    if (fieldsSource) {
      fieldsSource.setOnTable(state);
    }
  });

  // When a source is attached, the table gets a custom-columns button even if the
  // consumer didn't pass one. The source supplies CustomColumns via its components
  // bag (DI) so the implementation ships in the source's feature chunk, not the
  // table chunk.
  const SourceCustomColumns =
    state.collectionFieldsSource?.components.CustomColumns;
  const effectiveCustomColumns =
    customColumns ??
    (SourceCustomColumns ? <SourceCustomColumns /> : undefined);

  useColumnsSyncProps({
    toolbar: state,
    customColumns: effectiveCustomColumns,
    columns: tableColumns,
  });

  useEffect(() => {
    if (!dataExtension) {
      return;
    }
    (isValidElement<DataExtensionProps, DataExtensionType>(dataExtension)
      ? dataExtension.type
      : dataExtension
    ).syncTableCollectionProps(state);
  }, []);

  useEffect(() => {
    if (!dragAndDropReorderModeToolbar) {
      return;
    }
    dragAndDropReorderModeToolbar?.type.setReorderModeState(state);
  }, [state._dnd, dragAndDropReorderModeToolbar]);

  useEffect(() => state.selectionProps.set({ showSelection }), [showSelection]);
  useEffect(() => state.actionCell.set(actionCell), [actionCell]);

  if (selectionDisabled != null) {
    state.bulk.selectionDisabledProp =
      selectionDisabled as SelectionDisabledProp;
  }

  if (checkboxTooltipContent != null) {
    state.bulk.checkboxTooltipContentProp =
      checkboxTooltipContent as CheckboxTooltipContentProp;
  }

  return state;
}
