import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { Data } from '../../../types';
import { FormStation } from '../../FormStation';
import { IconName } from '../../Icons';
import {
  BulkEditRegistration,
  ExplorerBulkAction,
  ItemSelection,
} from '../Explorer.model';
import { BulkEditContext } from './BulkEditContext';
import { BulkEditFormFieldsConfigConverter } from './FormFieldsConfigConverter';

export interface useBulkEditProps<T extends Data> {
  bulkEditRegistration?: BulkEditRegistration<T>;
  getBulkActionSelection: () => ItemSelection<T>;
  collapseFilters: () => void;
}

export interface useBulkEditReturnType<T extends Data> {
  readonly isBulkEditMode: boolean;
  readonly BulkEditComponent: JSX.Element | null;
  readonly BulkEditContextProvider: React.FC;
  readonly bulkEditAction?: ExplorerBulkAction<T>;
  readonly closeBulkEdit: () => void;
}

export const useBulkEdit = <T extends Data>({
  bulkEditRegistration,
  getBulkActionSelection,
  collapseFilters,
}: useBulkEditProps<T>): useBulkEditReturnType<T> => {
  const [isBulkEditMode, setIsBulkEditMode] = useState<boolean>(false);
  const [noItemsSelected, setNoItemsSelected] = useState<boolean>(false);

  // Keep selection in a ref to avoid re-renders when the selection changes
  const selection = useRef<ItemSelection<T>>(getBulkActionSelection());

  useEffect(() => {
    selection.current = getBulkActionSelection();

    if (
      selection.current?.mode === 'SINGLE_ITEMS' &&
      selection.current.items &&
      selection.current.items.length === 0
    ) {
      setNoItemsSelected(true);
    } else {
      setNoItemsSelected(false);
    }
  }, [getBulkActionSelection]);

  const BulkEditContextProvider: React.FC = useCallback(
    ({ children }) => {
      return (
        <BulkEditContext.Provider
          value={{
            cancel: () => setIsBulkEditMode(false),
            isBulkEditMode,
          }}
        >
          {children}
        </BulkEditContext.Provider>
      );
    },
    [isBulkEditMode],
  );

  const bulkEditAction: ExplorerBulkAction<T> | undefined = useMemo(
    () =>
      bulkEditRegistration
        ? {
            label: bulkEditRegistration.label ?? 'Edit',
            icon: bulkEditRegistration.icon ?? IconName.BulkEdit,
            onClick: () => {
              setIsBulkEditMode((prev) => !prev);
              if (!isBulkEditMode) {
                collapseFilters();
              }
            },
          }
        : undefined,
    [bulkEditRegistration, collapseFilters, isBulkEditMode],
  );

  const handleSave = useCallback(
    async (data) => {
      await bulkEditRegistration?.saveData(data, selection.current);
    },
    [bulkEditRegistration],
  );

  const BulkEditContent = useMemo(() => {
    if (bulkEditRegistration?.component) {
      return bulkEditRegistration.component;
    } else if (bulkEditRegistration?.config) {
      return BulkEditFormFieldsConfigConverter(
        bulkEditRegistration?.config.fields,
      );
    }
    return null;
  }, [bulkEditRegistration?.component, bulkEditRegistration?.config]);

  const BulkEditComponent = useMemo(() => {
    return (
      <FormStation<T>
        defaultTitle="Bulk Edit Properties"
        saveData={handleSave}
        initialData={{ loading: false }}
        stationMessage={
          noItemsSelected
            ? { title: 'No items selected', type: 'warning' }
            : undefined
        }
        showSaveHeaderAction={!noItemsSelected}
        saveHeaderActionConfig={{ label: 'Apply', icon: IconName.Checkmark }}
        saveNotificationMessage="Your changes are being applied to the selected items."
      >
        {BulkEditContent}
      </FormStation>
    );
  }, [BulkEditContent, handleSave, noItemsSelected]);

  return {
    isBulkEditMode,
    BulkEditComponent,
    BulkEditContextProvider,
    bulkEditAction,
    closeBulkEdit: () => setIsBulkEditMode(false),
  };
};
