import React, { useState, useRef, useLayoutEffect, useEffect, useCallback, memo } from 'react';
import { useLocalize } from '~/hooks';

interface Option {
  value: string;
  label: string;
  icon?: React.ReactNode;
}

interface RadioProps {
  options: Option[];
  value?: string;
  onChange?: (value: string) => void;
  disabled?: boolean;
  className?: string;
  fullWidth?: boolean;
}

const Radio = memo(function Radio({
  options,
  value,
  onChange,
  disabled = false,
  className = '',
  fullWidth = false,
}: RadioProps) {
  const localize = useLocalize();
  const buttonRefs = useRef<(HTMLButtonElement | null)[]>([]);
  const [isMounted, setIsMounted] = useState(false);
  const [currentValue, setCurrentValue] = useState<string>(value ?? '');
  const [backgroundStyle, setBackgroundStyle] = useState<React.CSSProperties>({});

  const handleChange = (newValue: string) => {
    setCurrentValue(newValue);
    onChange?.(newValue);
  };

  const updateBackgroundStyle = useCallback(() => {
    const selectedIndex = options.findIndex((opt) => opt.value === currentValue);
    if (selectedIndex >= 0 && buttonRefs.current[selectedIndex]) {
      const selectedButton = buttonRefs.current[selectedIndex];
      const container = selectedButton?.parentElement;
      if (selectedButton && container) {
        const containerRect = container.getBoundingClientRect();
        const buttonRect = selectedButton.getBoundingClientRect();
        const offsetLeft = buttonRect.left - containerRect.left - 4;
        setBackgroundStyle({
          width: `${buttonRect.width}px`,
          transform: `translateX(${offsetLeft}px)`,
        });
      }
    }
  }, [currentValue, options]);

  // Mark as mounted after dialog animations settle
  // Timeout ensures we wait for CSS transitions to complete
  useEffect(() => {
    const timeout = setTimeout(() => {
      setIsMounted(true);
    }, 50);

    return () => clearTimeout(timeout);
  }, []);

  useLayoutEffect(() => {
    if (isMounted) {
      updateBackgroundStyle();
    }
  }, [isMounted, updateBackgroundStyle]);

  useLayoutEffect(() => {
    if (value !== undefined) {
      setCurrentValue(value);
    }
  }, [value]);

  if (options.length === 0) {
    return (
      <div
        className="relative inline-flex items-center rounded-lg bg-muted p-1 opacity-50"
        role="radiogroup"
      >
        <span className="px-4 py-2 text-xs text-muted-foreground">
          {localize('com_ui_no_options')}
        </span>
      </div>
    );
  }

  const selectedIndex = options.findIndex((opt) => opt.value === currentValue);

  return (
    <div
      className={`relative ${fullWidth ? 'flex' : 'inline-flex'} items-center rounded-lg bg-muted p-1 ${className}`}
      role="radiogroup"
    >
      {selectedIndex >= 0 && isMounted && (
        <div
          className="pointer-events-none absolute inset-y-1 rounded-md border border-border/50 bg-background shadow-sm transition-all duration-300 ease-out"
          style={backgroundStyle}
        />
      )}
      {options.map((option, index) => (
        <button
          key={option.value}
          ref={(el) => {
            buttonRefs.current[index] = el;
          }}
          type="button"
          role="radio"
          aria-checked={currentValue === option.value}
          onClick={() => handleChange(option.value)}
          disabled={disabled}
          className={`relative z-10 flex h-[34px] items-center justify-center gap-2 rounded-md px-4 text-sm font-medium transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${
            currentValue === option.value ? 'text-foreground' : 'text-foreground'
          } ${disabled ? 'cursor-not-allowed opacity-50' : ''} ${fullWidth ? 'flex-1' : ''}`}
        >
          {option.icon && (
            <span className="flex-shrink-0" aria-hidden="true">
              {option.icon}
            </span>
          )}
          <span className="whitespace-nowrap">{option.label}</span>
        </button>
      ))}
    </div>
  );
});

export default Radio;
