import React, { useRef, useEffect } from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';

const sizeList = ['small', 'medium'];

const Input = styled.input`
  position: absolute;
  clip: rect(0, 0, 0, 0);
`;

const Label = styled.label`
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: ${props => (props.size === 'small' ? 15 : 16)}px;
  font-weight: 600;
  user-select: none;
  cursor: ${props => (props.disabled ? 'not-allowed' : 'pointer')};

  ${props =>
    props.disabled &&
    `
    opacity: 0.5;
    cursor: not-allowed;
  `};
`;

const Indicator = styled.div`
  position: relative;
  width: ${props => (props.size === 'small' ? 16 : 20)}px;
  height: ${props => (props.size === 'small' ? 16 : 20)}px;
  background-color: ${props => props.theme.colors.white};
  border: solid 1.5px ${props => props.theme.colors.grey.v200};
  border-radius: ${props => (props.size === 'small' ? '5px' : '6px')};

  ${props =>
    props.rounded &&
    `
    border-radius: 50%;
  `};

  ${Input}:not(:disabled):checked + & {
    background-color: ${props => props.theme.checkboxes.default.bgColorChecked};
  }

  ${Label}:hover & {
    border-color: ${props => props.theme.colors.grey.v300};
  }

  ${Input}:focus + & {
    box-shadow: 0 0 0 3px ${props => props.theme.colors.grey.v200};
  }

  // Avoid hover on indicator when checkbox is disabled
  ${Input}:disabled + &,
  ${Input}:disabled + &:hover {
    background-color: ${props => props.theme.colors.grey.v100};
    border-color: ${props => props.theme.colors.grey.v300};
  }

  &::after {
    content: '';
    position: absolute;
    display: none;
    outline: none;
  }

  ${Input}:checked + &::after {
    display: block;
    position: absolute;
    width: 5px;
    height: 10px;
    margin-top: -0.0625em;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) rotate(45deg);
    border: solid ${props => props.theme.colors.white};
    border-width: 0 2px 2px 0;
  }

  ${Input}:indeterminate + & {
    background: ${props => props.theme.checkboxes.default.bgColorChecked};

    &::after {
      content: '';
      position: absolute;
      display: block;
      position: absolute;
      width: 9px;
      height: 2px;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: ${props => props.theme.colors.white};
    }
  }

  ${props =>
    props.size === 'small' &&
    `
    ${Input}:checked + &::after {
      width: 4px;
      height: 8px;
      border-width: 0 1.5px 1.5px 0;
    }

    ${Input}:indeterminate + &::after {
      width: 7px;
      height: 1.5px;
    }
  `};
`;

const Checkbox = ({ indeterminate = false, checked, value, onChange, name, id, label, size, rounded, disabled }) => {
  const checkboxRef = useRef();

  useEffect(() => {
    checkboxRef.current.indeterminate = indeterminate;
  }, [checkboxRef, indeterminate]);

  return (
    <Label htmlFor={id} size={size} disabled={disabled}>
      <Input type="checkbox" id={id} name={name} disabled={disabled} checked={checked} onChange={onChange} ref={checkboxRef} />
      <Indicator rounded={rounded} size={size} role="indicator" />
      {label}
    </Label>
  );
};

Checkbox.propTypes = {
  value: PropTypes.string,
  indeterminate: PropTypes.bool,
  checked: PropTypes.bool,
  onChange: PropTypes.func,
  label: PropTypes.string,
  name: PropTypes.string,
  id: PropTypes.string,
  size: PropTypes.oneOf(sizeList),
  rounded: PropTypes.bool,
  disabled: PropTypes.bool
};

export default Checkbox;
