import React from "react";
import PropTypes from "prop-types";
import TagsInput from "react-tagsinput";
import styled from "styled-components";
import { CloseIcon } from "@bufferapp/components/Icon/Icons";
import { Text, Button } from "@bufferapp/components";
import {
  gray,
  grayDark,
  grayDarker,
  blue,
  blueLighter,
} from "@bufferapp/ui/style/colors";
import {
  fontFamily,
  lineHeight,
  fontSize,
  fontWeight,
} from "@bufferapp/ui/style/fonts";

const Tag = styled.span`
  border-radius: 4px;
  padding: 4px;
  margin: 4px;
  color: white;
  font-weight: bold;
  background-color: ${blue};
`;

const Input = styled.input`
  font-family: ${fontFamily};
  font-size: ${fontSize};
  font-weight: ${fontWeight};
  line-height: ${lineHeight};
  color: ${grayDarker};
  max-width: 100%;
  width: 100%;
  padding: 9px 8px 8px 8px;
  border: none;
  border-radius: 4px;

  &:focus {
    outline: none;
  }

  &::placeholder {
    color: ${gray};
    font-family: ${fontFamily};
    font-size: ${fontSize};
    font-weight: ${fontWeight};
    line-height: ${lineHeight};
  }
`;

const TagContent = styled.span`
  display: inline-flex;
  align-items: center;
  white-space: nowrap;

  & > *:first-child {
    margin-right: 0.5rem;
  }
`;

const searchTag = ({ key, onRemove, getTagDisplayValue, tag, ...other }) => (
  <Tag key={key} {...other}>
    <Button noStyle onClick={() => onRemove(key)}>
      <TagContent>
        <Text color="white" size="mini">
          {getTagDisplayValue(tag)}
        </Text>
        <CloseIcon size="small" color="white" />
      </TagContent>
    </Button>
  </Tag>
);

searchTag.propTypes = {
  key: PropTypes.string.isRequired,
  onRemove: PropTypes.func.isRequired,
  getTagDisplayValue: PropTypes.func.isRequired,
  tag: PropTypes.string.isRequired,
};

const SearchWrapper = styled.div`
  border-radius: 4px;
  border: 1px solid ${gray};
  width: 100%;
  display: inline-flex;
  height: 38px;

  &:focus-within {
    border: 1px solid ${blue};
    box-shadow: 0px 0px 0px 3px ${blueLighter};
    transition-property: border-width, border-color, box-shadow;
    transition-duration: 0.1s;
    transition-timing-function: ease-in;
  }

  &:hover {
    border-color: ${grayDark};
  }
`;

const layout = (tags, input) => (
  <SearchWrapper>
    {tags} {input}
  </SearchWrapper>
);

const searchInput = (props) => (
  <Input
    {...props}
    value={props.value}
    type="text"
    placeholder={props.hasTags ? null : "Filter posts by keywords or #hashtags"}
  />
);

searchInput.propTypes = {
  value: PropTypes.string.isRequired,
  hasTags: PropTypes.bool.isRequired,
};

class Searchbox extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tags: [],
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleChangeInput = this.handleChangeInput.bind(this);
  }

  handleChange(tags) {
    this.props.search(tags);
  }

  handleChangeInput(tags) {
    this.setState({ tags });
  }

  render() {
    return (
      <TagsInput
        value={this.props.searchTerms}
        inputValue={this.state.tags}
        onChange={this.handleChange}
        onChangeInput={this.handleChangeInput}
        inputProps={{
          hasTags: this.props.searchTerms.length > 0,
        }}
        renderInput={searchInput}
        renderTag={searchTag}
        renderLayout={layout}
      />
    );
  }
}

Searchbox.defaultProps = {
  searchTerms: [],
};

Searchbox.propTypes = {
  search: PropTypes.func.isRequired,
  searchTerms: PropTypes.arrayOf(PropTypes.string),
};

export default Searchbox;
