// @flow
import React, { useEffect, useCallback } from 'react';
import styled from 'styled-components';
import { Box } from '../../../primitives';
import { ClickableSpan } from '../../typography/clickable-span';
import type { FormInputProps } from './form-input.proptypes';
import {
  getInputBorder,
  getInputHeight,
  getInputLeftPadding,
  getPlaceholderColor,
  getIconDataUri,
  getInputIconPosition,
  getTextColor,
} from './form-input.css-rules';
import { getPaletteColor } from '../../../mixins/branding';
import {
  getFontSize,
  getFontFamily,
  getFontWeight,
} from '../../../mixins/typography';

const StyledBox = styled(Box)`
  height: ${getInputHeight};
  border-radius: 6px;
  border: ${getInputBorder};
  border-color: ${getPaletteColor('greyscale-light')};
  max-width: 100%;
  background-color: white;

  :focus-within {
    border-color: ${getPaletteColor('greyscale-darker')};
  }
  &:not([disabled]):hover {
    border-color: ${getPaletteColor('greyscale-medium')};
  }
`;

const StyledInput = styled.input.attrs(({ large }) => ({
  fontSize: large ? 'f3' : 'f1',
  bold: large ? 'true' : undefined,
}))`
  color: ${getTextColor};
  font-family: ${getFontFamily};
  font-size: ${getFontSize};
  font-weight: ${getFontWeight};
  padding-bottom: 2px;
  padding-left: ${getInputLeftPadding};
  border: none;
  background-image: ${getIconDataUri};
  background-repeat: no-repeat;
  background-position: ${getInputIconPosition};
  margin-top: 5px;
  margin-bottom: 5px;
  flex-grow: 2;

  &&::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};
  }
`;

const StyledButton = styled(ClickableSpan)`
  font-family: ${getFontFamily};
  color: ${getPaletteColor('greyscale-darker')};
  width: auto;
  margin-right: 10px;
`;

export const FormInput = ({
  focusOnMount,
  onRef,
  onChange,
  id,
  hideBorder = false,
  ...props
}: FormInputProps<string>) => {
  const inputRef = React.useRef();

  // TODO: we should just let the component pass a ref in instead of
  // an onRef function. https://github.com/wealthsimple/patchwork/issues/771
  useEffect(() => {
    if (onRef && inputRef.current) {
      onRef(inputRef.current);
    }
  }, [onRef, inputRef]);

  const handleChange = useCallback(
    event => {
      onChange(event.target.value, event);
    },
    [onChange],
  );

  return (
    <StyledBox
      {...props}
      stacked="row"
      large={props.large}
      hideBorder={hideBorder}
    >
      <StyledInput
        {...props}
        id={id}
        ref={inputRef}
        type={props.type || 'text'}
        placeholder={props.placeholder || ''}
        disabled={props.disabled}
        value={props.value || ''}
        error={!!props.error}
        onChange={handleChange}
        onFocus={props.onFocus}
        onBlur={props.onBlur}
        large={props.large}
        iconType={props.iconType}
        iconPosition={props.iconPosition}
        autoFocus={focusOnMount}
        inputMode={props.inputMode}
        hideBorder={hideBorder}
      />
      {props.buttonText !== undefined && props.buttonText !== null ? (
        <StyledButton type="button" onClick={props.buttonPress}>
          {props.buttonText}
        </StyledButton>
      ) : null}
    </StyledBox>
  );
};

FormInput.displayName = 'FormInput';
