import { IdIconProps } from '@transferwise/icons';
import { clsx } from 'clsx';
import { FC, ReactNode, cloneElement, useId } from 'react';

import Body from '../../body';
import Chevron from '../../chevron';
import { Position, Size, Typography } from '../../common';
import Option from '../../common/Option';

export interface AccordionItemProps {
  /** A label for the accordion item, used for accessibility purposes. */
  'aria-label'?: string;
  /** An ID for the accordion item, used for accessibility purposes. */
  id?: string;
  /** The title of the accordion item. */
  title: ReactNode;
  /** The subtitle of the accordion item. */
  subtitle?: ReactNode;
  /** The content of the accordion item. */
  content: ReactNode;
  /** A callback function that is called when the accordion item is clicked. */
  onClick: () => void;
  /** Whether the accordion item is currently open or closed. */
  open: boolean;
  /** An optional icon to display next to the accordion item title. */
  icon?: ReactNode;
  /** @deprecated ... */
  theme?: 'light' | 'dark';
}

/**
 * AccordionItem
 *
 * A single item in an accordion component.
 *
 * @component
 * @param {string} [aria-label] - A label for the accordion item, used for accessibility purposes.
 * @param {string} [id] - An ID for the accordion item, used for accessibility purposes.
 * @param {ReactNode} title - The title of the accordion item.
 * @param {ReactNode} subtitle - The subtitle of the accordion item.
 * @param {ReactNode} content - The content of the accordion item.
 * @param {Function} onClick - A callback function that is called when the accordion item is clicked.
 * @param {boolean} open - Whether the accordion item is currently open or closed.
 * @param {ReactNode} [icon] - An optional icon to display next to the accordion item title.
 * @example
 * // Example usage:
 *
 * import AccordionItem from './AccordionItem';
 *
 * function App() {
 *   const handleItemClick = () => {
 *     console.log('Accordion item was clicked.');
 *   };
 *
 *   return (
 *     <AccordionItem
 *       title={<h2>Item Title</h2>}
 *       content={<p>Item content goes here.</p>}
 *       onClick={handleItemClick}
 *       open={true}
 *       icon={<Chevron />}
 *     />
 *   );
 * }
 */
const AccordionItem: FC<AccordionItemProps> = ({
  'aria-label': ariaLabel,
  id,
  title,
  subtitle,
  content,
  onClick,
  open,
  icon,
  theme = 'light',
}) => {
  const iconElement = icon
    ? cloneElement(icon as React.ReactElement<IdIconProps>, { size: 24 })
    : null;
  const fallbackId = useId();
  const accordionId = id ?? fallbackId;

  return (
    <div
      id={accordionId}
      className={clsx('np-accordion-item', iconElement ? 'np-accordion-item--with-icon' : null, {
        'np-accordion-item--open': open,
      })}
    >
      <Option
        aria-label={ariaLabel}
        as="button"
        media={iconElement}
        title={title}
        content={subtitle}
        button={<Chevron orientation={open ? Position.TOP : Position.BOTTOM} size={Size.MEDIUM} />}
        inverseMediaCircle={false}
        aria-expanded={open}
        aria-controls={`${accordionId}-section`}
        id={`${accordionId}-control`}
        onClick={onClick}
      />
      {open && (
        <div id={`${accordionId}-section`} role="region" aria-labelledby={`${accordionId}-control`}>
          <Body
            as="span"
            type={Typography.BODY_LARGE}
            className={clsx('np-accordion-item__content', 'd-block', {
              'has-icon': icon,
            })}
          >
            {content}
          </Body>
        </div>
      )}
    </div>
  );
};

export default AccordionItem;
