import React, { forwardRef, useMemo } from 'react';
import { View, Pressable, Animated } from 'react-native';
import Text from '../Text';
import { radioButtonStyles } from './RadioButton.styles';
import type { RadioButtonProps } from './types';
import { useRadioGroup } from './RadioGroup.native';
import { getNativeSelectionAccessibilityProps } from '../utils/accessibility';
import type { IdealystElement } from '../utils/refTypes';

const RadioButton = forwardRef<IdealystElement, RadioButtonProps>(({
  value,
  checked: checkedProp,
  onPress,
  disabled: disabledProp = false,
  label,
  size = 'md',
  intent = 'primary',
  // Spacing variants from FormInputStyleProps
  margin,
  marginVertical,
  marginHorizontal,
  style,
  testID,
  id,
  // Accessibility props
  accessibilityLabel,
  accessibilityHint,
  accessibilityDisabled,
  accessibilityHidden,
  accessibilityRole,
  accessibilityLabelledBy,
  accessibilityDescribedBy,
  accessibilityChecked,
}, ref) => {
  const group = useRadioGroup();

  const checked = group.value !== undefined ? group.value === value : checkedProp;
  const disabled = group.disabled || disabledProp;

  const animatedValue = React.useRef(new Animated.Value(checked ? 1 : 0)).current;

  React.useEffect(() => {
    Animated.spring(animatedValue, {
      toValue: checked ? 1 : 0,
      useNativeDriver: true,
      friction: 8,
      tension: 100,
    }).start();
  }, [checked, animatedValue]);

  const handlePress = () => {
    if (!disabled) {
      if (group.onValueChange) {
        group.onValueChange(value);
      } else if (onPress) {
        onPress();
      }
    }
  };

  // Generate native accessibility props
  const nativeA11yProps = useMemo(() => {
    const computedLabel = accessibilityLabel ?? label;
    const computedChecked = accessibilityChecked ?? checked;

    return getNativeSelectionAccessibilityProps({
      accessibilityLabel: computedLabel,
      accessibilityHint,
      accessibilityDisabled: accessibilityDisabled ?? disabled,
      accessibilityHidden,
      accessibilityRole: accessibilityRole ?? 'radio',
      accessibilityLabelledBy,
      accessibilityDescribedBy,
      accessibilityChecked: computedChecked,
    });
  }, [
    accessibilityLabel,
    label,
    accessibilityHint,
    accessibilityDisabled,
    disabled,
    accessibilityHidden,
    accessibilityRole,
    accessibilityLabelledBy,
    accessibilityDescribedBy,
    accessibilityChecked,
    checked,
  ]);

  // Apply variants for radio styles
  radioButtonStyles.useVariants({
    size,
    intent,
    checked,
    disabled,
    margin,
    marginVertical,
    marginHorizontal,
  });

  const dotScale = animatedValue.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 1],
  });

  return (
    <Pressable
      ref={ref as any}
      nativeID={id}
      onPress={handlePress}
      disabled={disabled}
      style={[radioButtonStyles.container, style]}
      testID={testID}
      {...nativeA11yProps}
    >
      <View style={radioButtonStyles.radio}>
        <Animated.View
          style={[
            radioButtonStyles.radioDot,
            {
              transform: [{ scale: dotScale }],
            },
          ]}
        />
      </View>
      {label && (
        <Text style={radioButtonStyles.label}>
          {label}
        </Text>
      )}
    </Pressable>
  );
});

RadioButton.displayName = 'RadioButton';

export default RadioButton;