// @flow
import React, { useCallback, useState } from 'react';
import styled from 'styled-components';
import randomstring from 'randomstring';

import { FieldLabel } from '../../typography';
import { HideAccessibly } from '../../../primitives/hide-accessibly';
import { getPaletteColor } from '../../../mixins/branding';
import {
  getFontSize,
  getFontFamily,
  getFontWeight,
} from '../../../mixins/typography';

import type { SearchInputFieldProps } from './search-input-field.proptypes';
import {
  LeftStyledSearchIcon,
  RightStyledSearchIcon,
  ClearInputButton,
} from './icons';

import {
  getSearchInputLeftPadding,
  getSearchInputFocusedLeftPadding,
} from './search-input-field.css-rules';

export const getInputHeight = ({ large }: SearchInputFieldProps) =>
  large ? '60px' : '40px';

const StyledSearchInputField = styled.input.attrs(({ bold, large }) => ({
  fontSize: large ? 'f3' : 'f1',
  bold: large ? 'true' : bold,
}))`
  && {
    background-color: ${getPaletteColor('white')};
    background-repeat: no-repeat;
    border: 1px solid ${getPaletteColor('greyscale-light')};
    border-radius: 6px;
    color: ${getPaletteColor('greyscale-black')};
    font-family: ${getFontFamily};
    font-size: ${getFontSize};
    font-weight: ${getFontWeight};
    height: ${getInputHeight};
    padding: 0;
    padding-left: ${getSearchInputLeftPadding};
    padding-right: 40px;
    width: 100%;

    &&::placeholder {
      /* Chrome, Firefox, Opera, Safari 10.1+ */
      color: ${getPaletteColor('greyscale-medium')};
      opacity: 1; /* Firefox */
    }

    &:focus {
      border: 1px solid ${getPaletteColor('greyscale-medium')};
      outline: none;
      padding-left: ${getSearchInputFocusedLeftPadding};

      &&::placeholder {
        color: transparent;
        opacity: 0; /* Firefox */
      }
    }
  }
`;

const SearchInputIcon = ({
  focused,
  hasValue,
  large,
}: {
  focused: boolean,
  hasValue: boolean,
  large: boolean,
}) => {
  const showGreySearchIcon = !focused && !hasValue;
  const showFocusedSearchIcon = focused && !hasValue;
  if (showGreySearchIcon) {
    return <LeftStyledSearchIcon large={large} />;
  }
  if (showFocusedSearchIcon) {
    return <RightStyledSearchIcon large={large} />;
  }
  return null;
};

export const SearchInputField = ({
  value,
  large = false,
  bold = false,
  hideLabel = false,
  label,
  placeholder,
  onChange,
}: SearchInputFieldProps) => {
  // Focused state
  const [focused, setFocused] = useState(false);
  const handleSearchInputFocused = useCallback(() => {
    setFocused(true);
  }, [setFocused]);
  const handleSearchInputBlurred = useCallback(() => {
    setFocused(false);
  }, [setFocused]);

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

  const handleClear = useCallback(() => {
    onChange('');
  }, [onChange]);

  const inputId = `input-${randomstring.generate(5)}`;
  const inputProps = {
    id: inputId,
    large,
    bold: bold ? 'true' : undefined,
    type: 'text',
    value,
    onChange: handleOnChange,
    onBlur: handleSearchInputBlurred,
    onFocus: handleSearchInputFocused,
    placeholder,
    hasDarkIcon: !!value,
  };

  return (
    <div style={{ position: 'relative' }}>
      {hideLabel ? (
        <HideAccessibly>
          <FieldLabel htmlFor={inputId}>{label}</FieldLabel>
        </HideAccessibly>
      ) : (
        <FieldLabel htmlFor={inputId} large={large}>
          {label}
        </FieldLabel>
      )}
      <div style={{ position: 'relative' }}>
        <SearchInputIcon
          focused={focused}
          hasValue={!!value.length}
          large={large}
        />
        <StyledSearchInputField {...inputProps} />
        <ClearInputButton
          large={large}
          onClick={handleClear}
          show={!!value.length}
        />
      </div>
    </div>
  );
};
