import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useHistory } from "react-router-dom";
import { BASE_PAGE, HOME_PAGE } from "../../constants/pages";
import { KEY_SEARCH } from "../../constants/queryStringConstants";
import {
  setManualSearchString,
  setSearchString,
} from "../../store/actions/filters/filtersActions";
import {
  selectManualSearchString,
  selectSearchString,
} from "../../store/selectors/filtersSelectors";
import { routeMatches } from "../../util/helpers/routeHelpers";

const useSearch = (applyAllFilters) => {
  const [searchStringLocally, setSearchStringLocally] = useState("");
  const [isInitallyLoaded, setIsInitiallyLoaded] = useState(false);
  const [appliedSearch, setAppliedSearch] = useState(false);
  const dispatch = useDispatch();
  const searchString = useSelector(selectSearchString);
  const history = useHistory();
  const manualSearchString = useSelector(selectManualSearchString);

  // On every global change of search string, new request to backend should be sent
  useEffect(() => {
    if (searchStringLocally !== searchString && applyAllFilters) {
      setSearchStringLocally(searchString);
    }
    if (isInitallyLoaded) {
      if (applyAllFilters) applyAllFilters();
    }
  }, [searchString]);

  // Empty search string when user navigates to other page
  useEffect(() => {
    if (
      (!routeMatches(HOME_PAGE) || !routeMatches(BASE_PAGE)) &&
      isInitallyLoaded
    ) {
      clear();
    }
    const queryObject = new URLSearchParams(history.location.search);
    if (queryObject.has(KEY_SEARCH)) {
      searchOffers(queryObject.get(KEY_SEARCH));
    } else {
      clear();
    }
  }, [history.location.pathname]);

  useEffect(() => {
    if (appliedSearch) {
      applyAllFilters();
      setAppliedSearch(false);
    }
  }, [appliedSearch]);

  // On every local change of search string, global state of search string should be also updated
  useEffect(() => {
    if (isInitallyLoaded && applyAllFilters) {
      dispatch(setSearchString(searchStringLocally));
    }
  }, [searchStringLocally]);

  const searchOffers = (searchValue) => {
    setIsInitiallyLoaded(true);
    setSearchStringLocally(searchValue);
  };

  const searchOffersImmediately = (searchValue) => {
    setIsInitiallyLoaded(true);
    searchOffers(searchValue);
    setAppliedSearch(true);
  };

  const setSearchStringManually = (searchValue) => {
    dispatch(setManualSearchString(searchValue));
  };

  const clear = () => {
    setSearchStringLocally("");
  };

  return {
    searchOffers,
    setSearchStringLocally,
    setSearchStringManually,
    searchOffersImmediately,
    searchStringLocally,
    searchString,
    manualSearchString,
    clear,
  };
};
export default useSearch;
