// @flow
import React, { useCallback } from 'react';
import randomstring from 'randomstring';
import { FieldLabel } from '../../typography/field-label';
import type { SelectProps } from './select.proptypes';
import { FormSelect } from './select.css-rules';
import { HideAccessibly, Box } from '../../../primitives';

const generateId = ({ id, prefix }: {| id?: string, prefix: string |}) => {
  const finalId =
    id === undefined
      ? `${prefix}-${randomstring.generate({
          length: 7,
          charset: 'alphabetic',
        })}`
      : id;

  return finalId;
};

const noop = () => {};

export const Select = ({
  children,
  disabled = false,
  error,
  className,
  placeholder,
  value,
  onBlur = noop,
  onFocus = noop,
  large,
  label,
  hideLabel = false,
  id,
  onChange,
  spacing,
  shrink,
  grow,
  basis,
  'data-qa': dataQa,
  'data-cy': dataCy,
}: SelectProps) => {
  const handleChange = useCallback(
    (event) => {
      const newValue = event.target.value;
      onChange(newValue === 'UNDEFINED' ? undefined : newValue);
    },
    [onChange],
  );
  const formSelectId = generateId({ id, prefix: 'select' });

  return (
    <Box
      stacked="column"
      className={className}
      {...{
        // $FlowFixMe upcast
        spacing,
        shrink,
        grow,
        basis,
      }}
      data-cy={dataCy}
      data-qa={dataQa}
      id={id}
    >
      {label !== undefined &&
        (hideLabel ? (
          <HideAccessibly>
            <FieldLabel htmlFor={formSelectId} large={large}>
              {label}
            </FieldLabel>
          </HideAccessibly>
        ) : (
          <FieldLabel htmlFor={formSelectId} large={large}>
            {label}
          </FieldLabel>
        ))}

      <FormSelect
        large={large}
        disabled={disabled}
        error={error}
        value={value == null && placeholder != null ? 'UNDEFINED' : value}
        onBlur={onBlur}
        onChange={handleChange}
        onFocus={onFocus}
        id={formSelectId}
      >
        {placeholder != null ? (
          <option value="UNDEFINED">{placeholder}</option>
        ) : null}
        {children}
      </FormSelect>
    </Box>
  );
};

Select.displayName = 'Select';
