// @flow
import React, { useMemo } from 'react';
import styled from 'styled-components';
import { v4 } from 'uuid';
import type { RadioButtonProps } from './radio-button.proptypes';
import { getFontFamily, getFontSize } from '../../../mixins/typography';
import { getPaletteColor } from '../../../mixins/branding';
import { Box } from '../../../primitives';
import { RadioOption } from '../../icon/radio-option';
import {
  getBaseFocusState,
  focusedBoxShadow,
  focusedBorderShadow,
  focusedBorderColor,
  focusedBorderRadius,
} from '../../../mixins/focus';
import { getSpacingRules } from '../../../mixins/spacing';

const RadioButtonContainer = styled(Box)`
  cursor: pointer;
  position: relative;
  ${getBaseFocusState({ hoverTransition: false, activeTransition: false })}
  &:focus-within {
    box-shadow: ${focusedBoxShadow},
      ${focusedBorderShadow} ${focusedBorderColor};
  }
  border-radius: ${focusedBorderRadius};
  transform: scale(1);
`;

const StyledRadioOption = styled(RadioOption)`
  margin-left: -${({ theme }) => theme.spacing.s1};
`;

const Label = styled.label`
  color: ${getPaletteColor('greyscale-black')};
  cursor: pointer;
  font-size: ${getFontSize};
  font-family: ${getFontFamily};
  display: flex;
  align-items: center;
  /* stylelint-disable property-no-vendor-prefix  */
  -webkit-touch-callout: none; /* iOS Safari */
  -webkit-user-select: none; /* Safari */
  -moz-user-select: none; /* Firefox */
  -ms-user-select: none; /* IE, Edge */
  /* stylelint-enable */
  user-select: none; /* Chrome, Opera */
  margin-top: 9px;
  margin-bottom: 11px;
  z-index: -1;
  ${getSpacingRules}
`;

const InvisibleInput = styled.input`
  height: 0;
  width: 0;
  margin: 0;
  padding: 0;
  opacity: 0;
  position: absolute;
`;

export const RadioButton = ({
  id,
  text,
  selected,
  onClick,
  name,
  spacing,
  grow,
  shrink,
  basis,
  onFocus,
  onBlur,
  className,
  'data-qa': dataQa,
  'data-cy': dataCy,
  stacked = 'row',
  align = 'center',
  justify,
  wrap,
  children,
  direction = 'left',
  ...props
}: RadioButtonProps) => {
  const onClickWithEvent = (_e) => onClick(id);
  const randomIdentifier = useMemo(() => v4(), []);
  const label = (
    <Label
      face="sans"
      fontSize="f1"
      htmlFor={randomIdentifier}
      spacing={direction === 'left' ? 'ml1' : 'mr1'}
    >
      {text != null ? text : children}
    </Label>
  );

  return (
    <RadioButtonContainer
      onClick={onClickWithEvent}
      onFocus={onFocus}
      onBlur={onBlur}
      spacing={spacing}
      {...{ grow, shrink, basis }}
      {...{ stacked, align, justify, wrap }}
      className={className}
      data-cy={dataCy}
      data-qa={dataQa}
      id={id}
    >
      <InvisibleInput
        readOnly
        type="radio"
        checked={selected}
        name={name}
        id={randomIdentifier}
        {...props}
      />
      {direction === 'left' ? (
        <>
          <StyledRadioOption checked={selected} />
          {label}
        </>
      ) : (
        <>
          {label}
          <StyledRadioOption checked={selected} />
        </>
      )}
    </RadioButtonContainer>
  );
};

RadioButton.displayName = 'RadioButton';
