// @flow
import React from 'react';
import styled from 'styled-components';
import MaskedInput from 'cleave.js/react';
import { FieldLabel } from '../../../typography/field-label';
import { Box } from '../../../../primitives';
import type { FloatingLabelInputProps } from './floating-label-input.proptypes';
import { getPaletteColor } from '../../../../mixins/branding';
import { getFontFamily, getFontSize } from '../../../../mixins/typography';
import { ErrorIcon } from '../../../icon';

const f3FontSize = ({ theme }) => getFontSize({ theme, fontSize: 'f3' });

const Input = styled(MaskedInput)`
  && {
    background: transparent;
    background-color: transparent;
    border: 0;
    font-family: ${getFontFamily};
    height: 100%;
    outline: none;
    padding: 21px 15px 0 20px;
    transition: height 0.3s, padding 0.3s;
    width: 100%;
    font-size: ${f3FontSize};
    font-weight: 600;

    &:focus:not(:disabled),
    &:active:not(:disabled),
    &:not([value='']):not(:disabled) {
      color: ${getPaletteColor('greyscale-black')};

      & + label {
        color: ${getPaletteColor('greyscale-black')};
        transform: translate3d(0, -14px, 0);

        span {
          transform: scale3d(0.8, 0.8, 1);
        }
      }
    }

    &:not([value='']):not(:focus) {
      padding: 10px 15px 10px 20px;

      & + label {
        opacity: 0;
        transform: translate3d(0, -18px, 0);
      }
    }
  }
`;

const FloatingLabel = styled(FieldLabel)`
  color: ${getPaletteColor('greyscale-dark')};
  left: 20px;
  margin-bottom: 0;
  pointer-events: none;
  position: absolute;
  transform: none;
  transition: opacity 0.3s, transform 0.3s, color 0.3s;
  font-size: ${f3FontSize};
  width: 100%;
  text-align: left;
`;

const FloatingLabelInputField = styled(Box)`
  align-items: center;
  font-size: ${f3FontSize};
  background: ${getPaletteColor('white')};
  border: 1px solid ${getPaletteColor('greyscale-light')};
  border-radius: 6px;
  cursor: text;
  display: flex;
  height: 60px;
  padding-right: 20px;
  position: relative;
  && {
    button {
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
`;

const StyledErrorIcon = styled(ErrorIcon)`
  position: absolute;
  top: 5px;
  right: 5px;
`;

const LabelText = styled.span`
  display: inline-block;
  transform: none;
  transform-origin: left;
  transition: transform 0.3s;
  /* To make labels of different character lengths scale down and the same rate and preserve alignment */
  min-width: 120px;
`;

export const FloatingLabelInput = ({
  id,
  'data-cy': dataCy,
  'data-qa': dataQa,
  type,
  onChange,
  label,
  children,
  inputMode,
  disabled,
  value,
  error,
  onBlur,
  onFocus,
  options,
  onRef,
  name,
}: FloatingLabelInputProps<string>) => {
  return (
    <FloatingLabelInputField>
      <Input
        id={id}
        type={type}
        disabled={disabled}
        data-qa={dataQa}
        data-cy={dataCy}
        value={value || ''}
        onChange={onChange}
        onFocus={onFocus}
        onBlur={onBlur}
        inputMode={inputMode}
        options={options}
        htmlRef={onRef}
        name={name}
        spellCheck={type === 'email' || type === 'password' ? false : undefined}
      />
      {/* Very important not to add any elements here or the selector handling the floating styles won't work  */}
      <FloatingLabel htmlFor={id}>
        <LabelText>{label}</LabelText>
      </FloatingLabel>
      {error != null && error !== false && <StyledErrorIcon />}
      {children}
    </FloatingLabelInputField>
  );
};
