/**
 * @file PageActionDropdowns.tsx - Portal-based component that injects Syncfusion DropDownButton menus into the PDF viewer's thumbnail sidebar.
 * Uses a MutationObserver to detect when thumbnail images are rendered, then creates React portals to render dropdown buttons as children of each thumbnail container.
 * A global click handler intercepts clicks on the dropdown buttons to prevent Syncfusion's own click handling from selecting the thumbnail page.
 *
 * Menu items include:
 * - rotate
 * - move up/down
 * - duplicate
 * - split
 * - revert
 * - delete page
 */

import {
  deletePageAtIndex,
  duplicatePageAtIndex,
  movePageAtIndex,
  type PageLevelActionsProps,
  revertPageAtIndex,
  rotatePageAtIndex,
  splitDocumentAtIndex,
} from '../../../../utils/pageLevelActions.ts';
import { type FC, useEffect, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import {
  DropDownButtonComponent,
  type MenuEventArgs,
} from '@syncfusion/ej2-react-splitbuttons';
import { TooltipComponent } from '@syncfusion/ej2-react-popups';
import { useDocument } from '../../../../contexts/DocumentContext.tsx';
import { useTranslation } from 'react-i18next';

/**
 * Props for the PageActionDropdowns component.
 */
interface PageActionDropdownsProps {
  /** Page-level action function props */
  props: PageLevelActionsProps;

  /** Whether the user's device is a mobile device */
  isDevice: boolean;

  /** Whether the user has permission to edit documents */
  hasEditPermission: boolean;

  /** Whether the user has permission to attach documents */
  hasAttachPermission: boolean;
}

/**
 * Injects a dropdown menu with page actions under each page thumbnail in the Syncfusion PDF Viewer.
 * Uses React portals to render Syncfusion DropDownButtonComponents into thumbnail container DOM nodes.
 * Not rendered on mobile devices or when the user lacks edit permission.
 */
export const PageActionDropdowns: FC<PageActionDropdownsProps> = ({
  props,
  isDevice,
  hasEditPermission,
  hasAttachPermission,
}) => {
  const { setThumbnailImagesVisible } = useDocument();

  // Track all thumbnail image DOM elements discovered via MutationObserver
  const [thumbnailImages, setThumbnailImages] = useState<Element[]>([]);
  // Dynamic refs for Syncfusion DropDownButtonComponent instances keyed by thumbnail index
  const dropdownButtonRefs = useRef<Map<number, DropDownButtonComponent>>(
    new Map()
  );

  // Set up MutationObserver to detect Syncfusion thumbnail rendering and register click interceptor
  useEffect(() => {
    const update = () => {
      const nodes = document.querySelectorAll('.e-pv-thumbnail-image');
      setThumbnailImagesVisible(nodes.length > 0);
      setThumbnailImages(Array.from(nodes));
    };

    // Initial check for thumbnail images
    update();

    // Global click handler (capture phase) to intercept dropdown button clicks and prevent Syncfusion from treating them as thumbnail page selections
    const clickHandler = (event: MouseEvent) => {
      const target = event.target as HTMLElement;
      const closest = target.closest('.page-action-dropdown');

      // Click event should only be blocked if the closest element has the "page-action-dropdown" class but not "e-dropdown-popup"
      // Allows click event to proceed as normal for dropdown menu items
      if (closest && !closest.className.includes('e-dropdown-popup')) {
        event.stopPropagation();
        event.preventDefault();

        const index = Number(closest.id.split('-').slice(-1));
        dropdownButtonRefs.current.get(index)?.toggle();
      }
    };
    document.addEventListener('click', clickHandler, true);

    // Observe DOM for Syncfusion dynamically adding/removing thumbnail elements
    const observer = new MutationObserver(() => {
      update();
    });
    observer.observe(document.body, { childList: true, subtree: true });

    return () => {
      observer.disconnect();
      document.removeEventListener('click', clickHandler, true);
    };
  }, []);

  const { t } = useTranslation(undefined, {
    keyPrefix:
      'components.processing.document_editor_panel.portals.page_action_dropdowns',
  });

  if (!hasEditPermission || isDevice) {
    return null;
  }

  return (
    <>
      {thumbnailImages.map((image, index) => {
        const parent = image.parentElement;
        if (!parent) {
          return null;
        }

        return createPortal(
          <TooltipComponent content={t('tooltip')} opensOn={'Hover'}>
            <DropDownButtonComponent
              id={`page-action-dropdown-${index}`}
              ref={(element: DropDownButtonComponent) => {
                if (element) {
                  dropdownButtonRefs.current.set(index, element);
                } else {
                  dropdownButtonRefs.current.delete(index);
                }
              }}
              items={[
                {
                  text: t('items.rotate_page_left'),
                  id: 'RotatePageLeft',
                },
                {
                  text: t('items.rotate_page_right'),
                  id: 'RotatePageRight',
                },
                {
                  separator: true,
                },
                {
                  text: t('items.move_page_up'),
                  id: 'MovePageUp',
                  disabled: thumbnailImages.length === 1 || !index,
                },
                {
                  text: t('items.move_page_down'),
                  id: 'MovePageDown',
                  disabled:
                    thumbnailImages.length === 1 ||
                    index + 1 === thumbnailImages.length,
                },
                {
                  separator: true,
                },
                {
                  text: t('items.duplicate_page'),
                  id: 'DuplicatePage',
                },
                {
                  separator: true,
                },
                {
                  text: t('items.split_at_page'),
                  id: 'SplitAtPage',
                  // No split for first page
                  disabled: !index || !hasAttachPermission,
                },
                {
                  separator: true,
                },
                {
                  text: t('items.revert_page'),
                  id: 'RevertPage',
                },
                {
                  text: t('items.delete_page'),
                  id: 'DeletePage',
                },
              ]}
              iconCss={'e-icons e-more-vertical-1'}
              cssClass={'e-flat mt-1 w-100 page-action-dropdown'}
              select={(args: MenuEventArgs) => {
                switch (args.item.id) {
                  case 'RotatePageLeft':
                    rotatePageAtIndex(props, index, -90);
                    break;
                  case 'RotatePageRight':
                    rotatePageAtIndex(props, index, 90);
                    break;
                  case 'MovePageUp':
                    movePageAtIndex(props, index, true);
                    break;
                  case 'MovePageDown':
                    movePageAtIndex(props, index, false);
                    break;
                  case 'DuplicatePage':
                    duplicatePageAtIndex(props, index);
                    break;
                  case 'SplitAtPage':
                    splitDocumentAtIndex(props, index);
                    break;
                  case 'RevertPage':
                    revertPageAtIndex(props, index);
                    break;
                  case 'DeletePage':
                    deletePageAtIndex(props, index);
                    break;
                }
              }}
            />
          </TooltipComponent>,
          parent
        );
      })}
    </>
  );
};
