// @flow
import React, { useCallback, useEffect, useRef } from 'react';
import MaskedInput from 'cleave.js/react';
import 'cleave.js/dist/addons/cleave-phone.ca';
import 'cleave.js/dist/addons/cleave-phone.gb';
import 'cleave.js/dist/addons/cleave-phone.us';
import styled from 'styled-components';
import type { MaskedTextInputProps } from './masked-text-input.proptypes';
import {
  getInputBorder,
  getInputHeight,
  getInputLeftPadding,
  getPlaceholderColor,
  getIconDataUri,
  getInputIconPosition,
  getTextColor,
} from './masked-text-input.css-rules';
import { getPaletteColor } from '../../../../mixins/branding';
import {
  getFontSize,
  getFontFamily,
  getFontWeight,
} from '../../../../mixins/typography';
import { Box } from '../../../../primitives';
import { getBaseFocusState } from '../../../../mixins/focus';
import { FloatingLabelInput } from '../floating-label-input/floating-label-input.component';

const StyledWrapper = styled(Box)`
  > input {
    height: ${getInputHeight};
    color: ${getTextColor};
    font-family: ${getFontFamily};
    font-size: ${getFontSize};
    font-weight: ${getFontWeight};
    padding-bottom: 2px;
    padding-left: ${getInputLeftPadding};
    border-radius: 6px;
    border: ${getInputBorder};
    border-color: ${getPaletteColor('greyscale-light')};
    background-image: ${getIconDataUri};
    background-repeat: no-repeat;
    background-position: ${getInputIconPosition};
    width: 100%;

    &:focus {
      border-color: ${getPaletteColor('greyscale-medium')};
      outline: none;
    }

    &&::placeholder {
      /* Chrome, Firefox, Opera, Safari 10.1+ */
      color: ${getPlaceholderColor};
      opacity: 1; /* Firefox */
    }

    &&::-ms-input-placeholder {
      /* Microsoft Edge */
      color: ${getPlaceholderColor};
    }

    &&:-ms-input-placeholder {
      /* Internet Explorer 10-11 */
      color: ${getPlaceholderColor};
    }

    ${getBaseFocusState({
      hoverTransition: false,
      activeTransition: false,
      pointerCursor: false,
    })}
  }
`;

export const MaskedTextInput = (props: MaskedTextInputProps<string>) => {
  const {
    onRef,
    focusOnMount,
    onChange,
    large,
    iconType,
    iconPosition,
    error,
    className,
    hideBorder = false,
    floatLabel,
    label,
  } = props;
  const textRef = useRef<HTMLInputElement | null>(null);
  const registerChild = useCallback(
    (ref) => {
      if (onRef != null) {
        onRef(ref);
      }
      textRef.current = ref;
    },
    [onRef, textRef],
  );
  const focusChild = useCallback(() => {
    if (textRef.current != null) {
      textRef.current.focus();
    }
  }, [textRef]);
  useEffect(() => {
    if (focusOnMount) {
      focusChild();
    }
  });
  const handleChange = useCallback(
    (event) => {
      onChange(event.target.value, event);
    },
    [onChange],
  );
  if (floatLabel) {
    return (
      <FloatingLabelInput
        label={label}
        options={props.options}
        id={props.id}
        type={props.type || 'text'}
        disabled={props.disabled}
        value={props.value || ''}
        onFocus={props.onFocus}
        onBlur={props.onBlur}
        onChange={handleChange}
        error={error}
      />
    );
  }
  return (
    <StyledWrapper
      className={className}
      fontSize={large ? 'f3' : 'f1'}
      bold={large}
      iconType={iconType}
      iconPosition={iconPosition}
      error={error}
      large={large}
      onFocus={props.onFocus}
      onBlur={props.onBlur}
      hideBorder={hideBorder}
    >
      <MaskedInput
        id={props.id}
        options={props.options}
        htmlRef={registerChild}
        type={props.type || 'text'}
        placeholder={props.placeholder || ''}
        disabled={props.disabled}
        value={props.value || ''}
        onFocus={props.onFocus}
        onBlur={props.onBlur}
        onChange={handleChange}
        inputMode={props.inputMode}
      />
    </StyledWrapper>
  );
};

MaskedTextInput.displayName = 'MaskedTextInput';
