import React, { useCallback, useState, useMemo } from 'react';
import { bem } from 'utils/bem';
import { ReusableModal, ModalSideBarConfig } from 'common/components/reusable-modal';
import { NoResults } from 'common/components/no-results';
import { TreeList, TreeNode } from 'common/components/tree-list';
import { SCustomColumnsModal } from './s-custom-columns-modal';
import { SelectedCustomColumnsSection } from './components';
import { IdNameField } from './types';
import { OptionIdType } from 'common/components/form/select';

export interface CustomColumnsModalProps<T extends IdNameField> {
  title: string;
  searchPlaceholder?: string;
  defaultColumnsIds: OptionIdType[];
  selectedColumnsIds: OptionIdType[];
  getSelectedColumns(ids: OptionIdType[]): T[];
  getColumns(search: string): TreeNode[];
  isOpened: boolean;
  isChanged: boolean;
  onSubmit(): void;
  onUpdate(items: OptionIdType[]): void;
  onRemove(item: OptionIdType): void;
  onClose(): void;
  dataSelector?: string;
}

const classes = bem('custom-columns-modal');

export const CustomColumnsModal = React.memo(
  <T extends IdNameField>({
    title,
    searchPlaceholder = 'Search',
    defaultColumnsIds,
    selectedColumnsIds,
    getSelectedColumns,
    getColumns,
    isOpened,
    isChanged,
    onSubmit,
    onUpdate,
    onRemove,
    onClose,
    dataSelector,
  }: CustomColumnsModalProps<T>) => {
    const [searchQuery, setSearchQuery] = useState('');

    const onModalClose = useCallback(() => {
      setSearchQuery('');
      onClose();
    }, [onClose]);

    const onModalSubmit = useCallback(() => {
      onSubmit();
      onModalClose();
    }, [onSubmit, onModalClose]);

    const columns = useMemo(() => getColumns(searchQuery), [getColumns, searchQuery]);

    const selectedColumns = useMemo(() => getSelectedColumns(selectedColumnsIds), [
      getSelectedColumns,
      selectedColumnsIds,
    ]);

    const onTreeListChange = useCallback(
      (ids: OptionIdType[]) => {
        onUpdate(ids);
      },
      [onUpdate]
    );

    const hasSelectedColumns = selectedColumnsIds.length > 0;
    const isSaveDisabled = !isChanged || !hasSelectedColumns;

    const sideBarConfig: ModalSideBarConfig = useMemo(
      () => ({
        component: (
          <SelectedCustomColumnsSection
            selectedColumns={selectedColumns}
            defaultColumnsIds={defaultColumnsIds}
            onUpdate={onUpdate}
            onRemove={onRemove}
          />
        ),
      }),
      [selectedColumns, defaultColumnsIds, onUpdate, onRemove]
    );

    return (
      <ReusableModal
        title={title}
        width="780px"
        height="600px"
        isOpen={isOpened}
        searchValue={searchQuery}
        searchPlaceholder={searchPlaceholder}
        onSearchChange={setSearchQuery}
        submitTooltipContent="Select at least one column"
        submitTooltipEnabled={!hasSelectedColumns}
        onClose={onModalClose}
        onSubmit={onModalSubmit}
        isSubmitDisabled={isSaveDisabled}
        sideBarConfig={sideBarConfig}
        hasSearch
        hasFooter
        dataSelector={dataSelector}
      >
        <SCustomColumnsModal data-selector="custom-columns-modal">
          {columns.length === 0 ? (
            <NoResults withFilters className={classes('empty-view')} />
          ) : (
            <TreeList
              nodes={columns}
              value={selectedColumnsIds}
              onChange={onTreeListChange}
              className={classes('metrics')}
              isExternallyFiltered={searchQuery?.length > 1}
            />
          )}
        </SCustomColumnsModal>
      </ReusableModal>
    );
  }
);
