import { type ReactNode, useId } from 'react';

import { tv } from 'tailwind-variants';

export interface RadioProps {
  name: string;
  value: string;
  checked?: boolean;
  defaultChecked?: boolean;
  onChange?: (value: string) => void;
  disabled?: boolean;
  readOnly?: boolean;
  children?: ReactNode;
  className?: string;
}

const radioStyles = tv({
  base: [
    'shrink-0 w-4 h-4 min-w-4 min-h-4 box-border rounded-full',
    'border-2 border-dabeeo-gray-be bg-white',
    'flex items-center justify-center',
    'transition-all duration-200',
    'peer-focus-visible:ring-2 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-primary',
  ],
  variants: {
    isSelected: {
      true: 'border-primary bg-primary',
    },
    isDisabled: {
      true: 'border-dabeeo-gray-be bg-dabeeo-gray-eb',
    },
    isReadOnly: {
      true: '',
    },
  },
  compoundVariants: [
    {
      isSelected: true,
      isDisabled: true,
      className: 'border-dabeeo-gray-be bg-dabeeo-gray-eb',
    },
  ],
});

const innerCircleStyles = tv({
  base: 'w-2 h-2 rounded-full transition-all duration-200',
  variants: {
    isSelected: {
      true: 'bg-white',
      false: 'bg-transparent',
    },
    isDisabled: {
      true: 'bg-dabeeo-gray-eb',
    },
  },
  compoundVariants: [
    {
      isSelected: true,
      isDisabled: true,
      className: 'bg-dabeeo-gray-eb',
    },
  ],
});

const labelStyles = tv({
  base: 'text-dabeeo-black-22 text-sm font-medium inline-flex items-center',
  variants: {
    isDisabled: {
      true: 'text-dabeeo-gray-be',
    },
  },
});

export const Radio = (props: RadioProps) => {
  const { name, value, checked, defaultChecked, onChange, disabled, readOnly, children, className } = props;
  const id = useId();
  const isInteractive = !disabled && !readOnly;

  return (
    <label
      htmlFor={id}
      className={`inline-flex h-9 items-center gap-2.5 ${isInteractive ? 'cursor-pointer' : 'cursor-not-allowed'} ${className ?? ''}`}
    >
      <input
        type="radio"
        id={id}
        name={name}
        value={value}
        checked={checked}
        defaultChecked={defaultChecked}
        onChange={(e) => isInteractive && onChange?.(e.target.value)}
        disabled={disabled}
        readOnly={readOnly}
        className="sr-only peer"
      />
      <span className={radioStyles({ isSelected: checked, isDisabled: disabled, isReadOnly: readOnly })}>
        <span className={innerCircleStyles({ isSelected: checked, isDisabled: disabled })} />
      </span>
      {children && <span className={labelStyles({ isDisabled: disabled })}>{children}</span>}
    </label>
  );
};
