import React from 'react';
import { cn } from '@/lib/utils';
import FormLabel from './FormLabel';
import FormError from './FormError';

/**
 * FormRadio Component
 * Radio button group with custom styling and keyboard navigation
 */

export interface RadioOption {
  value: string;
  label: string;
  disabled?: boolean;
  description?: string;
}

export interface FormRadioProps {
  label?: string;
  error?: string | string[];
  helpText?: string;
  required?: boolean;
  options: RadioOption[];
  value?: string;
  onChange?: (value: string) => void;
  containerClassName?: string;
  radioClassName?: string;
  disabled?: boolean;
  id?: string;
  name?: string;
  layout?: 'vertical' | 'horizontal';
}

export const FormRadio: React.FC<FormRadioProps> = ({
  label,
  error,
  helpText,
  required = false,
  options,
  value,
  onChange,
  containerClassName,
  radioClassName,
  disabled = false,
  id,
  name,
  layout = 'vertical',
}) => {
  const hasError = !!error;
  const showError = hasError;

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (onChange) {
      onChange(e.target.value);
    }
  };

  const inputId = id || (label ? label.toLowerCase().replace(/\s+/g, '-') : undefined);
  const groupName = name || inputId;

  const baseRadioClasses = cn(
    'w-4 h-4 border rounded-full transition-all duration-200',
    'focus:outline-none focus:ring-2 focus:ring-primary',
    {
      'border-neutral-dark bg-neutral-light': !hasError,
      'border-danger': hasError,
      'opacity-60 cursor-not-allowed': disabled,
      'cursor-pointer': !disabled,
    },
    radioClassName
  );

  const selectedIndicatorClasses = cn(
    'w-2.5 h-2.5 rounded-full bg-primary transition-all duration-200',
    {
      'scale-0': false,
      'scale-100': true,
    }
  );

  const containerClasses = cn(
    'flex flex-col gap-2',
    {
      'gap-3': layout === 'vertical',
      'gap-4 flex-row flex-wrap': layout === 'horizontal',
    },
    containerClassName
  );

  const optionWrapperClasses = cn(
    'flex items-start gap-2',
    {
      'opacity-60': disabled,
    }
  );

  const labelClasses = cn(
    'text-sm font-medium leading-none cursor-pointer',
    {
      'text-text-primary': !hasError,
      'text-danger': hasError,
    }
  );

  const descriptionClasses = 'text-xs text-text-secondary mt-0.5';

  return (
    <div className={cn('flex flex-col gap-1.5', containerClassName)}>
      {label && (
        <FormLabel htmlFor={inputId} required={required}>
          {label}
        </FormLabel>
      )}

      <div
        className={containerClasses}
        role="radiogroup"
        aria-labelledby={inputId ? `${inputId}-label` : undefined}
        aria-invalid={hasError}
      >
        {options.map((option) => {
          const optionId = `${inputId}-${option.value}`;
          const isChecked = value === option.value;

          return (
            <div key={option.value} className={optionWrapperClasses}>
              <div className="relative flex items-center justify-center">
                <input
                  type="radio"
                  id={optionId}
                  name={groupName}
                  value={option.value}
                  checked={isChecked}
                  onChange={handleChange}
                  disabled={disabled || option.disabled}
                  required={required}
                  aria-describedby={helpText || showError || option.description ? `${inputId}-error ${optionId}-desc` : undefined}
                  className={cn(
                    baseRadioClasses,
                    option.disabled && 'opacity-50',
                    isChecked && 'border-primary'
                  )}
                />
                
                {isChecked && (
                  <div className="absolute inset-0 flex items-center justify-center pointer-events-none">
                    <div className={selectedIndicatorClasses} />
                  </div>
                )}
              </div>
              
              <div className="flex-1">
                <label
                  htmlFor={optionId}
                  className={cn(
                    labelClasses,
                    option.disabled && 'opacity-50'
                  )}
                >
                  {option.label}
                </label>
                
                {option.description && (
                  <p
                    className={descriptionClasses}
                    id={`${optionId}-desc`}
                  >
                    {option.description}
                  </p>
                )}
              </div>
            </div>
          );
        })}
      </div>

      {helpText && (
        <p className="text-xs text-text-secondary" id={`${inputId}-help`}>
          {helpText}
        </p>
      )}

      {showError && (
        <FormError errors={error} id={`${inputId}-error`} />
      )}
    </div>
  );
};

FormRadio.displayName = 'FormRadio';

export default FormRadio;