import React, { useMemo } from 'react';
import type { Key, ReactElement } from 'react';
import type { StyleProp, ViewStyle } from 'react-native';
import AccordionItem from './AccordionItem';
import { Spacer, StyledWrapper } from './StyledAccordion';
import { usePropsOrInternalState } from '../../utils/hooks';

export interface AccordionProps<K extends Key> {
  /**
   * List of accordion items to be rendered. Each item must have an unique key.
   */
  items: {
    header: string | ReactElement;
    content: ReactElement;
    key: K;
    style?: StyleProp<ViewStyle>;
    testID?: string;
  }[];
  /**
   * Key of the active item.
   * When activeItemKey and onItemPress is passed, the component is fully controlled.
   * Otherwise, it would be uncontrolled.
   */
  activeItemKey?: K;
  /**
   * Callback invoked when an item is pressed.
   */
  onItemPress?: (key: K) => void;
  /**
   * Item type.
   */
  variant?: 'default' | 'card';
  /**
   * Additional style.
   */
  style?: StyleProp<ViewStyle>;
  /**
   * Testing id of the component.
   */
  testID?: string;
  /**
   * If true, indicates that the Accordion is accessible to screen readers.
   */
  accessible?: boolean;
}

const Accordion = <K extends Key>({
  items,
  activeItemKey,
  onItemPress,
  variant = 'default',
  style,
  testID,
  accessible,
}: AccordionProps<K>) => {
  const defaultValue = useMemo(
    () => (typeof activeItemKey === 'number' ? NaN : '') as K,
    [activeItemKey]
  );
  const [_activeItemKey, _onItemPress] = usePropsOrInternalState<K>(
    defaultValue,
    activeItemKey,
    onItemPress
  );

  return (
    <StyledWrapper style={style} testID={testID} accessible={accessible}>
      {items.map(({ key, ...props }, index) => {
        const open = _activeItemKey === key;
        return (
          <React.Fragment key={key}>
            {variant === 'card' && index !== 0 && (
              <Spacer testID="accordion-spacer" />
            )}
            <AccordionItem
              {...props}
              open={open}
              onPress={() => _onItemPress(open ? defaultValue : key)}
              variant={variant}
            />
          </React.Fragment>
        );
      })}
    </StyledWrapper>
  );
};

export default Accordion;
