import { PopoverMenu, Button, ButtonProps } from '@wix/design-system';
import React, {
  ReactNode,
  useMemo,
  useCallback,
  MutableRefObject,
  RefObject,
} from 'react';
import { ChevronDown } from '@wix/wix-ui-icons-common';
import {
  ActionSubItemPrivate,
  ActionSubitemLabelPrivate,
} from './ActionSubItemProps';
import { DisabledTooltip } from '../DisabledTooltip';

function isActionSubitemLabel(
  item: NonNullable<ActionSubItemPrivate['subItems']>[number][number],
): item is ActionSubitemLabelPrivate {
  return typeof item === 'object' && item !== null && 'sectionTitle' in item;
}

export function ActionPopover(props: {
  actionItem: ActionSubItemPrivate;
  size?: ButtonProps['size'];
  priority?: ButtonProps['priority'];
  fullWidth?: ButtonProps['fullWidth'];
  onPopoverClick?: () => void;
}) {
  const { actionItem, size, priority, onPopoverClick, fullWidth } = props;
  const { dataHook, subItems, popoverMenuProps } = actionItem;

  const createCombinedRef = useCallback(
    (wdsRef?: RefObject<HTMLElement>) => {
      return (wrapper: HTMLDivElement | null) => {
        const buttonEl = wrapper?.querySelector('button') ?? null;

        if (wdsRef) {
          (wdsRef as MutableRefObject<HTMLElement | null>).current = buttonEl;
        }

        const externalRef = actionItem.ref;
        if (externalRef) {
          if (typeof externalRef === 'function') {
            externalRef(buttonEl);
          } else {
            (externalRef as MutableRefObject<HTMLElement | null>).current =
              buttonEl;
          }
        }
      };
    },
    [actionItem.ref],
  );

  const allActions = useMemo(() => {
    return subItems
      ?.filter((subItemGroup) => subItemGroup?.length)
      .reduce<ReactNode[]>((result, group, index, array) => {
        const nodes: ReactNode[] = [];

        group.forEach((item, itemIndex) => {
          if (isActionSubitemLabel(item)) {
            nodes.push(
              <PopoverMenu.SectionTitle
                key={`section-${index}-${itemIndex}`}
                title={item.sectionTitle}
                dataHook={item.dataHook}
              />,
            );
          } else {
            nodes.push(
              <PopoverMenu.MenuItem
                prefixIcon={item.prefixIcon}
                disabled={item.disabled}
                text={item.label}
                key={item.label}
                subtitle={item.subtitle}
                dataHook={item.dataHook}
                onClick={item.onClick}
              />,
            );
          }
        });

        if (index !== array.length - 1) {
          nodes.push(<PopoverMenu.Divider key={`divider-${index}`} />);
        }

        return [...result, ...nodes];
      }, []);
  }, [subItems]);

  return (
    <PopoverMenu
      {...popoverMenuProps}
      dataHook={dataHook ? `${dataHook}-popover` : undefined}
      triggerElement={({ toggle, ref: wdsRef }) => (
        // Wrapper div needed due to type mismatch: PopoverMenu expects RefObject<HTMLElement>
        // but Button's ref returns a class instance, not an HTMLElement.
        <div ref={createCombinedRef(wdsRef)} style={{ display: 'contents' }}>
          <DisabledTooltip
            content={actionItem.tooltip}
            dataHook={dataHook ? `${dataHook}-tooltip` : undefined}
          >
            <Button
              skin="standard"
              priority={priority}
              size={size}
              fullWidth={fullWidth}
              dataHook={actionItem.dataHook}
              onClick={() => {
                onPopoverClick?.();
                toggle();
              }}
              ellipsis
              prefixIcon={actionItem.prefixIcon}
              disabled={actionItem.disabled}
              suffixIcon={<ChevronDown />}
            >
              {actionItem.label}
            </Button>
          </DisabledTooltip>
        </div>
      )}
    >
      {allActions}
    </PopoverMenu>
  );
}
