import type { ReactNode } from 'react';
import { useId } from 'react';
import type { RadioGroupProps as AriaRadioGroupProps, RadioProps as AriaRadioProps } from 'react-aria-components';
import { Radio as AriaRadio, RadioGroup as AriaRadioGroup, composeRenderProps } from 'react-aria-components';

import clsx from 'clsx';
import { tv } from 'tailwind-variants';

export type RadioOption = {
  value: string;
  label: ReactNode;
  isDisabled?: boolean;
};

export interface RadioGroupProps extends AriaRadioGroupProps {
  items: RadioOption[];
}

export const RadioGroup = (props: RadioGroupProps) => {
  const radioGroupId = useId();
  const { items, className, value, ...restProps } = props;
  return (
    <AriaRadioGroup
      className={clsx('flex gap-4 data-[orientation=vertical]:flex-col data-[orientation=vertical]:gap-3', className)}
      value={value === '' ? null : value}
      {...restProps}
    >
      {items.map((item) => {
        return (
          <Radio key={`radio_group-${radioGroupId}-${item.value}`} value={item.value} isDisabled={item.isDisabled}>
            {item.label}
          </Radio>
        );
      })}
    </AriaRadioGroup>
  );
};

interface RadioProps extends AriaRadioProps {}

const radioStyles = tv({
  base: 'shrink-0 w-4 h-4 box-border rounded-full border-[1.5px] border-dabeeo-gray-be bg-white transition-all',
  variants: {
    isSelected: {
      true: 'border-4 border-primary ',
    },
    isFocusVisible: {
      true: 'ring-2 ring-offset-2 ring-primary',
    },
    isInvalid: {
      true: 'border-dabeeo-red',
    },
    isDisabled: {
      true: 'border-dabeeo-gray-be',
    },
  },
  compoundVariants: [{ isDisabled: true, isSelected: false, className: 'bg-dabeeo-gray-eb' }],
});
export const Radio = (props: RadioProps) => {
  const { className, ...restProps } = props;
  return (
    <AriaRadio
      className={clsx(
        'inline-flex items-center gap-2.5 text-dabeeo-black-22 text-sm font-medium data-disabled:text-dabeeo-gray-be',
        className
      )}
      {...restProps}
    >
      {composeRenderProps(props.children, (children, renderProps) => (
        <>
          <div className={radioStyles(renderProps)} />
          {children}
        </>
      ))}
    </AriaRadio>
  );
};
