import React, { useState, useEffect, useRef } from 'react';

import Icon from '../Icon';
import Divider from '../Divider';

import {
  Wrapper,
  Selected,
  Content,
  InputContent,
  OptionWrapper,
  Option,
} from './styled';

type Option = {
  key: string | number;
  content: React.ReactNode;
};

type Props = {
  onChange?: (item: Option | React.ReactNode) => void;
  options: Option[];
  defaultValue?: React.ReactNode;
  isDivide?: boolean;
  width?: string;
  useInput?: boolean;
  style?: {};
};

const SelectBox: React.FunctionComponent<Props>= ({
  onChange,
  options ,
  defaultValue,
  isDivide,
  width = 'auto',
  useInput = false,
  style,
}) => {
  const selectRef = useRef<HTMLDivElement>(null);
  const optionRef = useRef<HTMLDivElement>(null);
  const [isCollapse, setCollapse] = useState(true);
  const [value, setValue] = useState(defaultValue);

  const handleClick = () => {
    setCollapse(!isCollapse);
  }

  const handleSelect = (index: number) => {
    setValue(options[index].content);

    if (onChange) {
      onChange(options[index]);
    }
  }

  const handleBlur = () => {
    setCollapse(true);
  }

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setValue(e.target.value || 0);
  }

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.keyCode === 13 && onChange && value) {
      onChange(value);
      setCollapse(true);
    }
  }

  useEffect(() => {
    if (!defaultValue || options[0]) {
      setValue(options[0].content);
    }
  }, []);

  useEffect(() => {
    if (!isCollapse && selectRef.current) {
      const position = selectRef.current.getBoundingClientRect();
      if (optionRef.current) {
        optionRef.current.style.top = `${selectRef.current.clientHeight + position.top}px`;
        optionRef.current.style.left = `${position.left}px`;
      }
    }
  });

  return (
    <Wrapper width={width} style={style}>
      <Selected
        ref={selectRef}
        onMouseDown={handleClick}
        onBlur={handleBlur}
        tabIndex={0}
      >
        {
          useInput && (typeof value === "string" || typeof value === "number") ? (
            <InputContent
              value={value}
              onChange={handleChange}
              onKeyDown={handleKeyDown}
            />
          ) : (
            <Content>
              {value}
            </Content>
          )
        }
        {isDivide ? <Divider /> : null}
        <Icon glyph="down-arrow" />
      </Selected>
      {
        !isCollapse ? (
          <OptionWrapper ref={optionRef}>
            {
              options.map((option: Option, index: number) => (
                <Option
                  key={option.key}
                  onMouseDown={() => { handleSelect(index); }}
                >
                  {option.content}
                </Option>
              ))
            }
          </OptionWrapper>
        ) : null
      }
    </Wrapper>
  );
};

SelectBox.defaultProps = {
  defaultValue: '',
  onChange: () => {},
  isDivide: false,
};

export default SelectBox;
