import { Scale } from '@engie-group/fluid-types';
import React, {
  ComponentPropsWithoutRef,
  PropsWithChildren,
  useContext,
  useEffect,
  useRef
} from 'react';
import { Utils } from '../../utils/util';
import { NJAccordionContext } from './NJAccordionContext';

export type NJAccordionItemProps = PropsWithChildren &
  ComponentPropsWithoutRef<'details'> & {
    /**
     * Size of the Accordion item
     */
    scale?: Extract<Scale, 'lg' | 'md'>;

    /**
     * Whether the toggle icon is place at the start of the item or not.
     */
    hasLeadingToggleIcon?: boolean;
    /**
     * Whether the toggle use the alternative icons (plus/minus) or th default ones (chevron)
     */
    hasAlternativeToggleIcon?: boolean;
    /**
     * Custom leading icon
     */
    icon?: React.ReactElement<unknown>;
  };

export const NJAccordionItem = React.forwardRef<HTMLDetailsElement, NJAccordionItemProps>(
  (
    { children, scale, hasLeadingToggleIcon, hasAlternativeToggleIcon, icon, className, ...props },
    forwardedRef
  ) => {
    const { setHasAlternativeToggleIcon, setCustomIcon } = useContext(NJAccordionContext);

    useEffect(() => {
      setHasAlternativeToggleIcon?.(hasAlternativeToggleIcon);
    }, [hasAlternativeToggleIcon]);

    useEffect(() => {
      setCustomIcon?.(icon);
    }, [icon]);

    const ref = useRef<HTMLDetailsElement>(null);
    const newRef = Utils.mergeRefs([forwardedRef, ref]);
    const onToggle = (e: React.ToggleEvent<HTMLDetailsElement>) => {
      if (e.nativeEvent.newState === 'open' || e.currentTarget.open) {
        const allItems = document.querySelectorAll(`details.nj-accordion-item[name=${props.name}]`);
        allItems.forEach((item) => {
          if (item !== ref.current) {
            item.removeAttribute('open');
          }
        });
      }
      props.onToggle?.(e);
    };

    const classNames = Utils.classNames(
      'nj-accordion-item',
      {
        [`nj-accordion-item--${scale}`]: !!scale && scale !== 'md',
        [`nj-accordion-item--leading-toggle`]: hasLeadingToggleIcon
      },
      className
    );

    return (
      <details ref={newRef} {...props} onToggle={onToggle} className={classNames}>
        {children}
      </details>
    );
  }
);

NJAccordionItem.displayName = 'NJAccordionItem';
