// @flow
import React, { useState, useRef, useLayoutEffect } from 'react';
import randomstring from 'randomstring';
import type { ComponentType } from 'react';
import styled, { withTheme } from 'styled-components';
import type { TextAreaProps } from './textarea.proptypes';
import type { ThemeProps } from '../../../types';
import { Box } from '../../../primitives';
import { FieldLabel } from '../../typography/field-label';
import { HideAccessibly } from '../../../primitives/hide-accessibly';
import { getPaletteColor } from '../../../mixins/branding';
import {
  getFontSize,
  getFontFamily,
  getFontWeight,
} from '../../../mixins/typography';
import {
  FOCUS_VISIBLE_SELECTOR,
  getBaseFocusState,
} from '../../../mixins/focus';
import { getTextColor } from '../form-input/form-input.css-rules';
import { getTextareaHeight, getResizable } from './textarea.css-rules';

const StyledTextarea = styled.textarea.attrs(() => ({
  fontSize: 'f1',
}))`
  width: 100%;
  height: ${getTextareaHeight};
  color: ${getTextColor};
  font-family: ${getFontFamily};
  font-size: ${getFontSize};
  font-weight: ${getFontWeight};
  border-radius: 6px;
  border: 1px solid ${getPaletteColor('greyscale-light')};
  padding: 10px 20px;
  resize: ${getResizable};
  ${getBaseFocusState({
    hoverTransition: false,
    activeTransition: false,
    pointerCursor: false,
  })}
  ${FOCUS_VISIBLE_SELECTOR} {
    border: 1px solid ${getPaletteColor('greyscale-darker')};
  }
  &:not([disabled]):hover {
    border: 1px solid ${getPaletteColor('greyscale-medium')};
  }
`;

const _TextArea = ({
  id = '',
  placeholder,
  label,
  value,
  disabled,
  focusOnMount,
  resize = false,
  hideLabel = false,
  height,
  onChange = (
    _value: string,
    _event: SyntheticInputEvent<HTMLInputElement>,
  ) => {},
  onBlur = () => {},
  onFocus = () => {},
  className = '',
}: {|
  ...TextAreaProps<string>,
  ...ThemeProps,
|}) => {
  const textareaId = `textarea-${id}-${randomstring.generate(5)}`;
  const [managedValue, setValue] = useState(value);

  const handleChange = (evt) => {
    const newValue = evt.target.value;
    onChange(newValue, evt);
    setValue(newValue);
  };
  const textareaRef = useRef();
  useLayoutEffect(() => {
    if (focusOnMount && textareaRef.current) {
      textareaRef.current.focus();
    }
  }, [focusOnMount]);

  return (
    <Box stacked="column" className={className}>
      {hideLabel ? (
        <HideAccessibly>
          <FieldLabel htmlFor={textareaId}>{label}</FieldLabel>
        </HideAccessibly>
      ) : (
        <FieldLabel htmlFor={textareaId}>{label}</FieldLabel>
      )}

      <StyledTextarea
        ref={textareaRef}
        id={textareaId}
        resize={resize}
        placeholder={placeholder}
        value={managedValue}
        height={height}
        focusOnMount={focusOnMount}
        onChange={handleChange}
        onBlur={onBlur}
        onFocus={onFocus}
        disabled={disabled}
      />
    </Box>
  );
};

export const TextArea: ComponentType<TextAreaProps<string>> = withTheme(
  _TextArea,
);

TextArea.displayName = 'TextArea';
