import React, {Component} from "react";
import {connect} from "react-redux";
import {withRouter} from "react-router-dom";
import classnames from "classnames";

//strings
import strings from "../constants/localization";

//actions
import {chatSearchResult as chatSearchResultAction} from "../actions/chatActions";
import {threadGetList} from "../actions/threadActions";
import {contactGetList} from "../actions/contactActions";

//components
import AsideSearchFilter from "./AsideSearchFilter";
import Shape, {ShapeCircle} from "../../../Talk-ui-kit/src/shape";
import Container from "../../../Talk-ui-kit/src/container";
import Gap from "../../../Talk-ui-kit/src/gap";
import {InputText} from "../../../Talk-ui-kit/src/input";
import {LoadingSpinner} from "../../../Talk-ui-kit/src/loading";
import {MdClose, MdOutlineFilterAlt} from "react-icons/md";

//styling
import style from "../../styles/app/AsidSearch.scss";
import utilsStyle from "../../styles/utils/utils.scss";

//statics

function buildParams(state) {
  const {unreadChecked, time} = state;
  const params = {};
  if (time) {
    params.fromTime = time.fromTime;
    params.toTime = time.toTime;
  }
  if (unreadChecked) {
    params.new = true;
  }
  return Object.keys(params).length ? params : null;
}

@connect(store => {
  return {
    chatSearchShow: store.chatSearchShow,
    chatSearchResult: store.chatSearchResult
  };
})
class AsideSearch extends Component {

  constructor(props) {
    super(props);
    this.onSearchQueryChange = this.onSearchQueryChange.bind(this);
    this.onClearSearchClick = this.onClearSearchClick.bind(this);
    this.onAdvancedFilterClick = this.onAdvancedFilterClick.bind(this);
    this.setSettings = this.setSettings.bind(this);
    this.inputRef = React.createRef();
    this.state = {
      advanceFilterShow: false,
      query: "",
      time: null,
      unreadChecked: false,
      loading: false
    }
  }

  componentDidUpdate(oldProps, oldState) {
    const {chatSearchShow, chatSearchResult} = this.props;
    const {query, time, unreadChecked} = this.state;
    const {chatSearchShow: oldChatSearchShow, chatSearchResult: oldChatSearchResult} = oldProps;
    const {time: oldTime, unreadChecked: oldunreadChecked} = oldState;

    if (oldTime !== time || unreadChecked !== oldunreadChecked) {
      this.search(query);
    }

    if (oldChatSearchResult !== chatSearchResult) {
      if (!chatSearchResult) {
        this.onClearSearchClick();
      }
    }
    if (chatSearchShow) {
      if (!oldChatSearchShow) {
        if (this.inputRef.current) {
          this.inputRef.current.focus();
        }
      }
    } else {
      if (oldChatSearchShow) {
        if (this.inputRef.current) {
          this.onClearSearchClick();
        }
      }
    }
  }

  onSearchQueryChange(event) {
    const value = event.target.value;
    this.setState({
      query: value
    });
    clearTimeout(this.toSearchTimoutId);
    if (!value.slice()) {
      return this.search(value.slice());
    }

    this.toSearchTimoutId = setTimeout(e => {
      clearTimeout(this.toSearchTimoutId);
      this.search(value);
    }, 750);
  }

  onLoading(loading) {
    this.setState({
      loading
    })
  }

  search(query) {
    const {dispatch} = this.props;
    const params = buildParams(this.state);
    this.onLoading(false);
    if (query) {
      const threadPromise = dispatch(threadGetList(0, 50, query, true, params));
      const contactPromise = dispatch(contactGetList(0, 50, query, false, true));
      this.onLoading(true);
      Promise.all([threadPromise, contactPromise]).then(result => {
        this.onLoading(false);
        dispatch(chatSearchResultAction(true, result[0].threads, result[1].contacts));
      });
    } else {
      if (params) {
        this.onLoading(true);
        return dispatch(threadGetList(0, 50, null, true, params)).then(result => {
          this.onLoading(false);
          dispatch(chatSearchResultAction(true, result.threads, []));
        });
      }
      dispatch(chatSearchResultAction());
    }
  }

  onClearSearchClick() {
    this.onLoading(false);
    this.setState({
      query: ""
    });
    this.props.dispatch(chatSearchResultAction());
  }

  onAdvancedFilterClick() {

    this.setState({
      advanceFilterShow: !this.state.advanceFilterShow
    });
  }

  setSettings(settingKey, value) {
    this.setState({
      [settingKey]: value
    });
  }

  render() {
    const {chatSearchShow} = this.props;
    const {query, advanceFilterShow, time, unreadChecked, loading} = this.state;
    const iconSize = style.iconSizeMd.replace("px", "");
    const classNames = classnames({
      [style.AsideSearch]: true,
      [style["AsideSearch--show"]]: chatSearchShow
    });
    const hasFilter = time || unreadChecked;
    const filterIsOn = advanceFilterShow || hasFilter;
    return (
      <Container className={classNames} ref={this.container}>
        <Container display="flex" alignItems="center">
          <Container flex="1 1 0" relative>
            <InputText className={style.AsideSearch__InputContainer} inputClassName={style.AsideSearch__Input}
                       onChange={this.onSearchQueryChange} value={query} placeholder={strings.search}
                       ref={this.inputRef}/>
            {((query && query.slice()) || loading) &&
            <Container centerLeft display="flex" alignItems="center" justifyContent="center">

              {
                loading &&
                <LoadingSpinner size={20} primaryColor={style.colorAccent} width={2}/>
              }

              {
                !!(query && query.slice()) && <MdClose size={iconSize}
                                                       className={utilsStyle["u-clickable"]}
                                                       onClick={this.onClearSearchClick}
                                                       style={{color: style.colorAccent}}/>
              }
              <Gap xl={20}/>

            </Container>
            }
          </Container>
          <Container relative>
            <MdOutlineFilterAlt size={iconSize}
                                className={utilsStyle["u-clickable"]}
                                onClick={this.onAdvancedFilterClick}
                                style={{
                                  color: filterIsOn ? style.colorAccent : style.colorGrayDark,
                                  marginLeft: "20px"
                                }}/>
            {
              hasFilter && <Container className={style.AsideSearch__HasFilterContainer}>
                <Shape color="accent"
                       size="xs">
                  <ShapeCircle/>
                </Shape>
              </Container>

            }

          </Container>
        </Container>
        <AsideSearchFilter isOpen={advanceFilterShow}
                           setSettings={this.setSettings}
                           settings={this.state}
                           clearSettings={this.clearAdvancedFilter}/>
      </Container>
    )
  }
}

export default withRouter(AsideSearch);