import {
  Box,
  Divider,
  PopoverMenuProps,
  TableToolbar,
  Text,
  TextButton,
} from '@wix/design-system';
import React, { cloneElement, useEffect, useState } from 'react';
import { observer } from 'mobx-react-lite';
import { useToolbarCollectionContext } from '../ToolbarCollectionContext';
import { st, classes } from './MultiBulkActionToolbar.st.css.js';
import { ActionControl, ActionPopover, ActionSubitem } from '../ActionControl';
import { useWixPatternsContainer } from '@wix/bex-core/react';
import { MultiBulkActionToolbarState } from './MultiBulkActionToolbarState';
import { useExtensionMenuItems } from '../../hooks/useExtensionMenuItems';
import { BulkActionContainer } from './BulkActionContainer';
import { useIsMobile } from '../../hooks/useIsMobile';
import { useBulkActionMobileGroups } from '../../hooks/useBulkActionMobileGroups';

export interface MultiBulkActionToolbarProps {
  /**
   * List of primary actions. Primary actions are displayed as individual buttons.
   * @overrideType [ActionSubitem[]](./?path=/story/common-types--actionsubitem)
   * @external
   */
  primaryActionItems?: ActionSubitem[];

  /**
   * List of secondary actions. Secondary actions are displayed when clicking the More Actions menu.
   * Secondary actions can be grouped by using an array of arrays, and a divider will be added between each group.
   * @external
   * @overrideType [ActionSubitem[]](./?path=/story/common-types--actionsubitem) | [ActionSubitem[][]](./?path=/story/common-types--actionsubitem)
   */
  secondaryActionItems?: ActionSubitem[] | ActionSubitem[][];

  /**
   * [PopoverMenu](https://www.docs.wixdesignsystem.com/?path=/story/components-overlays--popovermenu) props to pass to the 'More Action' popover menu.
   * @external
   */
  secondaryActionsPopoverMenuProps?: Partial<PopoverMenuProps>;

  /**
   * This ID is used to specify the target container for [dashboard menu plugin](./?path=/story/features-enrich-slots-and-plugins--slots-and-plugins) items.
   */
  containerId?: string;

  /**
   * This prop is used to pass additional properties that can be used on the onClick of the container's extensions menu items.
   */
  containerProps?: Record<string, any>;
}

function _MultiBulkActionToolbar(props: MultiBulkActionToolbarProps) {
  const {
    primaryActionItems,
    secondaryActionItems,
    secondaryActionsPopoverMenuProps,
    containerId,
    containerProps,
  } = props;
  const toolbarCollectionState = useToolbarCollectionContext();
  const extensionMenuItems = useExtensionMenuItems({
    containerId,
    containerProps,
  });
  const isMobile = useIsMobile();

  const [state] = useState(
    () =>
      new MultiBulkActionToolbarState({
        extensionMenuItems,
        collection: toolbarCollectionState.collection,
      }),
  );

  useEffect(() => {
    state.setActions({
      primaryActionItems,
      secondaryActionItems,
    });
  }, [primaryActionItems, secondaryActionItems]);

  const { collection, hasToolbarTabs, featuredComponents, bulk } =
    toolbarCollectionState;

  const { maxSelection, total, selectedCountOrTotal, allSelected } = bulk;

  const { value: exportButton } = featuredComponents.exportButton;

  const TagsAssignButton =
    toolbarCollectionState.tagsCollectionState?.components.AssignButton;

  const { translate: t } = useWixPatternsContainer();

  const withBi = (item: ActionSubitem, ctaIndex: number): ActionSubitem => {
    return {
      ...item,
      onClick: () => {
        toolbarCollectionState.toolbarBIReporter.ctaClicked({
          itemId: bulk.selectedIds.join(','),
          location: 'multiBulkActionToolbar',
          ctaName: item.biName ?? '',
          ctaIndex,
          componentId: (item as any).componentId,
          appId: (item as any).appId,
          numCtas:
            state.primaryActionItems.length + state.secondaryActionItemsCount,
        });
        item?.onClick();
      },
    };
  };

  const mobileBulkActionGroups = useBulkActionMobileGroups({
    primaryActionItems: state.primaryActionItems,
    secondaryActionItems: state.secondaryActionItems,
    moreActionsLabel: t('cairo.moreActions'),
  });

  const mobileBulkActionGroupsWithBi = mobileBulkActionGroups?.map((group) =>
    group.map((item, itemIndex) => withBi(item, itemIndex + 1)),
  );

  const bulkActionButtonsDesktop = (
    <>
      <Box alignSelf="stretch" marginLeft="SP4" marginRight="SP2">
        <Divider direction="vertical" />
      </Box>

      <Box gap="SP1" className={st(classes.root)}>
        {TagsAssignButton && (
          <BulkActionContainer>
            <TagsAssignButton />
          </BulkActionContainer>
        )}
        {exportButton && (
          <BulkActionContainer>
            {cloneElement(exportButton, {
              toolbarType: 'bulkActionToolbar',
            })}
          </BulkActionContainer>
        )}
        {state.primaryActionItems
          .filter((x) => !!x)
          .map((actionItem, index) => (
            <BulkActionContainer key={index}>
              <ActionControl
                priority="secondary"
                size="small"
                actionItem={{
                  dataHook: 'bulk-action-button',
                  ...actionItem,
                  subItems: (actionItem?.subItems as ActionSubitem[][])?.map(
                    (subItemsGroup) =>
                      subItemsGroup?.map((subItem, subIndex) => ({
                        ...subItem,
                        onClick: () => {
                          toolbarCollectionState.toolbarBIReporter.ctaClicked({
                            itemId: bulk.selectedIds.join(','),
                            location: 'multiBulkActionToolbar',
                            ctaName: subItem.biName ?? '',
                            ctaIndex: subIndex + 1, // Missing BI requirements https://jira.wixpress.com/browse/CAIRO-600?focusedCommentId=9989131
                            moreActionsIndex: subIndex + 1,
                            componentId: (subItem as any).componentId,
                            appId: (subItem as any).appId,
                            numCtas:
                              state.primaryActionItems.length +
                              state.secondaryActionItemsCount,
                          });
                          subItem.onClick?.();
                        },
                      })),
                  ),
                  onClick: () => {
                    toolbarCollectionState.toolbarBIReporter.ctaClicked({
                      itemId: bulk.selectedIds.join(','),
                      location: 'multiBulkActionToolbar',
                      ctaName: actionItem.biName ?? '',
                      ctaIndex: 1, // Missing BI requirements https://jira.wixpress.com/browse/CAIRO-600?focusedCommentId=9989131
                      moreActionsIndex: 0,
                      componentId: (actionItem as any).componentId,
                      appId: (actionItem as any).appId,
                      numCtas:
                        state.primaryActionItems.length +
                        state.secondaryActionItemsCount,
                    });
                    actionItem.onClick?.();
                  },
                }}
              />
            </BulkActionContainer>
          ))}

        {state.secondaryActionItems.filter(
          (secondaryActionItemsGroup) => secondaryActionItemsGroup.length > 0,
        ).length > 0 && (
          <BulkActionContainer>
            <ActionPopover
              priority="secondary"
              size="small"
              actionItem={{
                dataHook: 'more-actions',
                biName: 'more-actions',
                subItems: (() => {
                  let index = 0;
                  return state.secondaryActionItems.map((subItemGroup) =>
                    subItemGroup.map((subItem) => {
                      const subItemIndex = index;
                      index++;
                      const _subItem = {
                        ...subItem,
                        onClick: () => {
                          toolbarCollectionState.toolbarBIReporter.ctaClicked({
                            itemId: bulk.selectedIds.join(','),
                            location: 'multiBulkActionToolbar',
                            ctaName: subItem.biName ?? '',
                            ctaIndex: subItemIndex + 3,
                            moreActionsIndex: subItemIndex + 1,
                            componentId: (subItem as any).componentId,
                            appId: (subItem as any).appId,
                            numCtas:
                              state.primaryActionItems.length +
                              state.secondaryActionItemsCount,
                          });
                          subItem.onClick?.();
                        },
                      };
                      return _subItem;
                    }),
                  );
                })(),

                popoverMenuProps: secondaryActionsPopoverMenuProps,
                label: t('cairo.moreActions'),
              }}
            />
          </BulkActionContainer>
        )}
      </Box>
    </>
  );

  const bulkActionButtonsMobile = (
    <ActionPopover
      priority="secondary"
      size="small"
      actionItem={{
        dataHook: 'all-actions-mobile',
        biName: 'more-actions',
        subItems: mobileBulkActionGroupsWithBi,
        popoverMenuProps: {
          fixed: false,
          minWidth: 'max-content',
          ...secondaryActionsPopoverMenuProps,
        },
        label: t('cairo.table.mobile.more.button'),
      }}
    />
  );

  return (
    <Box minHeight="60px">
      <TableToolbar
        removeVerticalPadding={hasToolbarTabs}
        dataHook="bulk-action-toolbar"
      >
        <TableToolbar.ItemGroup position="start" className={st(classes.root)}>
          <Box direction="horizontal" className={st(classes.leftGroupWrapper)}>
            <TableToolbar.Item className={st(classes.selectedCountItem)}>
              <Text
                ellipsis
                size="small"
                weight="thin"
                dataHook="selected-count"
                className={st(classes.selectedCountText)}
              >
                {maxSelection !== undefined
                  ? t('cairo.bulkActions.max.selection', {
                      max: maxSelection,
                      total: selectedCountOrTotal,
                    })
                  : collection.result.supportTotal &&
                    collection.result.totalStatus === 'success'
                  ? t('cairo.bulkSelectedWithTotal', {
                      num: selectedCountOrTotal,
                      total,
                    })
                  : allSelected
                  ? ''
                  : t('cairo.bulkSelected', {
                      num: selectedCountOrTotal,
                    })}
              </Text>
            </TableToolbar.Item>

            {collection.result.supportTotal && (
              <TableToolbar.Item>
                <TextButton
                  dataHook="select-all"
                  size="small"
                  onClick={() =>
                    bulk.toggleSelectAll({ location: 'TableToolbar CTA' })
                  }
                >
                  {bulk.hasClickableRows
                    ? t('cairo.selectAll')
                    : t('cairo.deselectAll')}
                </TextButton>
              </TableToolbar.Item>
            )}

            {!isMobile && bulkActionButtonsDesktop}
          </Box>
        </TableToolbar.ItemGroup>

        {isMobile && (
          <TableToolbar.ItemGroup position="end">
            <TableToolbar.Item>{bulkActionButtonsMobile}</TableToolbar.Item>
          </TableToolbar.ItemGroup>
        )}
      </TableToolbar>
    </Box>
  );
}

export const MultiBulkActionToolbar = observer(_MultiBulkActionToolbar);
