import type { ReactElement } from 'react';
import React from 'react';
import type { StyleProp, ViewStyle } from 'react-native';
import { View } from 'react-native';
import Radio from './Radio';
import { Spacer } from './StyledRadio';
import type { OptionType } from './types';

export interface RadioGroupProps<T> {
  /**
   * An array of radio options to be selected.
   */
  options: OptionType<T>[];
  /**
   * Radio input value.
   */
  value: T;
  /**
   * Press event handler receiving selected radio's value.
   */
  onPress: (value: T) => void;
  /**
   * Used to extract a unique key for a given option at the specified index. Key is used for caching and as the react key to track item re-ordering.
   * The default extractor checks option.key, and then falls back to using the index, like React does.
   */
  keyExtractor?: (option: OptionType<T>, index?: number) => string;
  /**
   * Additional style.
   */
  style?: StyleProp<ViewStyle>;
  /**
   * Testing id of the component.
   */
  testID?: string;
  /**
   * Overrides the text that's read by the screen reader when the user interacts with the element.
   */
  accessible?: boolean;
  /**
   * Idle background color of the Radio.
   */
  inactiveIntent?: 'light' | 'dark';
}

function getKey<T>(
  option: OptionType<T>,
  index: number,
  keyExtractor?: (opt: OptionType<T>, i?: number) => string
) {
  let key: React.Key = '';
  if (keyExtractor !== undefined) {
    key = keyExtractor(option, index);
  } else if (option.key !== undefined) {
    key = option.key;
  } else {
    key = index;
  }

  return key;
}

const RadioGroup = <T,>({
  value,
  onPress,
  options,
  keyExtractor,
  style,
  testID,
  accessible,
  inactiveIntent = 'light',
}: RadioGroupProps<T>): ReactElement => (
  <View style={style} testID={testID} accessible={accessible}>
    {options.map((option, index) => (
      <React.Fragment key={getKey(option, index, keyExtractor)}>
        {index !== 0 && <Spacer themeIntent={inactiveIntent} />}
        <Radio
          text={option.text}
          subText={option.subText}
          checked={option.value === value}
          onPress={() => onPress(option.value)}
          inactiveIntent={inactiveIntent}
          prefix={option.prefix}
        >
          {option.children}
        </Radio>
      </React.Fragment>
    ))}
  </View>
);

export default RadioGroup;
