import React, { ReactNode, useContext } from "react";
import classNames from "classnames";
import { useId } from "@reach/auto-id";
import { Box } from "../Box";
import { Stack, StackProps } from "../Stack";
import { Input, InputProps } from "../Input";
import { Label } from "../Label";
import { Text } from "../Text";
import { bem } from "../../utilities/bem";
import isUndefined from "../../utilities/isUndefined";
import { ORIENTATION } from "../../types";
import { FormGroupContext } from "../FormGroup/FormGroupContext";

const cn = "Radio";

interface RadioProps extends InputProps {
  label: ReactNode;
  isLabelHidden?: boolean;
}

const RadioGroup = (props: StackProps) => {
  const { orientation = ORIENTATION.VERTICAL, ...rest } = props;

  return <Stack orientation={orientation} {...rest} />;
};

export const Radio = (props: RadioProps) => {
  const {
    label,
    id: idProp,
    checked,
    disabled,
    className,
    defaultValue,
    isLabelHidden = false,
    theme: themeProp,
    ...rest
  } = props;

  const fallbackId = `radio:${useId()}`;
  const id = isUndefined(idProp) ? fallbackId : idProp;
  const { theme: themeContext } = useContext(FormGroupContext);
  const theme = themeProp || themeContext;

  const checkboxWrapClassname = classNames(
    bem(`${cn}Wrap`),
    disabled && bem(`${cn}Wrap`, { m: "isDisabled" }),
    isLabelHidden && bem(`${cn}Wrap`, { m: "isLabelHidden" }),
    className,
  );

  return (
    <Label className={checkboxWrapClassname} hideRequiredStyles>
      <Box className={bem(`${cn}Wrap`, { e: "control" })}>
        <Box className={bem(cn)}>
          <Input
            id={id}
            type="radio"
            checked={checked}
            disabled={disabled}
            className={bem(cn, { e: "input" })}
            defaultValue={defaultValue}
            aria-checked={checked ? "true" : "false"}
            {...rest}
          />
          <Box
            className={classNames(
              bem(cn, { e: "backdrop" }),
              bem(cn, { e: "backdrop", m: theme }),
            )}
          />
          <Box
            className={classNames(
              bem(cn, { e: "icon" }),
              bem(cn, { e: "icon", m: theme }),
            )}
          />
        </Box>
      </Box>

      <Text
        as="span"
        className={classNames(
          bem(`${cn}Wrap`, { e: "text" }),
          bem(`${cn}Wrap`, { e: "text", m: theme }),
        )}
      >
        {label}
      </Text>
    </Label>
  );
};

Radio.Group = RadioGroup;
