import React, { ReactNode, useEffect, useMemo } from 'react';
import { PopoverMenu, PopoverMenuProps } from '@wix/design-system';
import { cairoPageCtaClicked, cairoTpaSCtaClicked } from '@wix/bex-core/bi';
import {
  useCollectionPageContext,
  useWixPatternsContainer,
} from '@wix/bex-core/react';
import { observer } from 'mobx-react-lite';
import { useExtensionMenuItems } from '../../hooks/useExtensionMenuItems';
import { ExtensionMenuItem } from '../../state';
import { usePageButtonBiParams } from '../usePageButtonBiParams';
import { useExploreAppsState } from './useExploreAppsState';
import { MoreActionsItem } from './MoreActionsItem';
import { MoreActionsProps } from './MoreActionsProps';
import { CollectionPageState, WixPatternsContainer } from '@wix/bex-core';

export type MoreActionItemFactory = (params: {
  pageState: CollectionPageState;
  container: WixPatternsContainer;
}) => MoreActionsItem;

export type MoreActionsPropItem = MoreActionsItem | MoreActionItemFactory;

export interface MoreActionsBaseProps
  extends MoreActionsProps,
    Pick<PopoverMenuProps, 'triggerElement'> {}

function _MoreActionsBase(params: MoreActionsBaseProps) {
  const {
    items = [],
    containerId,
    containerProps,
    dataHook = 'more-actions',
    triggerElement,
    exploreAppsModalProps,
    biAdditionalInfo,
  } = params;
  const { pageType, location } = usePageButtonBiParams();
  const state = useExtensionMenuItems({ containerId, containerProps });
  const container = useWixPatternsContainer();
  const pageState = useCollectionPageContext();
  const { reportBi, environment } = container;

  useEffect(() => {
    const notifyLoad = async () => {
      const { loadStart, loadEnd } = await import('@wix/bex-core/bi');
      reportBi(
        loadStart({
          componentType: 'More actions',
          componentName: environment.componentName,
          additionalFeaturesAvailability: `IsUsingExploreApps: ${!!exploreAppsModalProps}`,
        }),
      );
      reportBi(
        // We dont care about loading time, its just needed for usage purposes
        loadEnd({
          componentType: 'More actions',
          url: window.location.href,
          route: window.location.pathname,
          componentName: environment.componentName,
        }),
      );
    };
    notifyLoad();
  }, []);

  const groupedItems = Array.isArray(items?.[0]) ? items : [items];

  const exploreAppsState = useExploreAppsState(exploreAppsModalProps);

  const allActions = useMemo(() => {
    const groups = [...groupedItems, state.menuItems] as (
      | MoreActionsPropItem
      | ExtensionMenuItem
    )[][];

    if (exploreAppsState) {
      groups.push([exploreAppsState.moreActionsMenuItem]);
    }

    const numCtas = groups.reduce((result, group) => result + group.length, 0);
    const flatActions = groups.flat();

    return groups
      .filter((actions) => actions.length !== 0)
      .reduce<ReactNode[]>((result, group, index, array) => {
        return [
          ...result,
          ...group.map((item) => {
            const { prefixIcon, text, onClick, biName, ...rest } =
              typeof item === 'function'
                ? item({ pageState, container })
                : item;
            const isTPA = 'type' in item && item.type === 'TPA';
            const itemAdditionalInfo =
              'biAdditionalInfo' in item ? item.biAdditionalInfo : undefined;

            return (
              <PopoverMenu.MenuItem
                key={index}
                prefixIcon={prefixIcon}
                text={text}
                onClick={() => {
                  reportBi(
                    cairoPageCtaClicked({
                      ctaName: biName,
                      ctaType: 'More Actions Option',
                      location,
                      moreActionsIndex: flatActions.indexOf(item),
                      numCtas,
                      section: isTPA ? 'TPA' : 'Vertical',
                      componentType: 'Page',
                      pageType,
                      additionalInfo: itemAdditionalInfo,
                    }),
                  );

                  if (isTPA) {
                    reportBi(
                      cairoTpaSCtaClicked({
                        appId: item.appId,
                        componentType: 'Page',
                        numCtas,
                        ctaIndex: flatActions.indexOf(item),
                        ctaName: biName,
                        location,
                        tpaComponentId: item.componentId,
                      }),
                    );
                  }

                  onClick(isTPA ? state.containerProps : undefined);
                }}
                {...rest}
              />
            );
          }),
          ...(index !== array.length - 1
            ? [<PopoverMenu.Divider key={index} />]
            : []),
        ];
      }, []);
  }, [items, state.menuItems, exploreAppsState]);

  return allActions.length === 0 ? null : (
    <>
      <PopoverMenu
        dataHook={dataHook}
        onShow={() => {
          reportBi(
            cairoPageCtaClicked({
              ctaName: 'More Actions',
              ctaType: 'secondary page dropdown',
              location,
              componentType: 'Page',
              pageType,
              additionalInfo: biAdditionalInfo,
            }),
          );
        }}
        minWidth={240}
        textSize="medium"
        triggerElement={triggerElement}
        appendTo="parent"
        zIndex={1101}
      >
        {allActions}
      </PopoverMenu>
      {exploreAppsState && <exploreAppsState.Modal state={exploreAppsState} />}
    </>
  );
}

export const MoreActionsBase = observer(_MoreActionsBase);
