import React, { useCallback, useEffect, useState } from "react";

import { useDispatch, useSelector } from "react-redux";

import Spotlight from "@enact/spotlight";

import { getSearch, resetSearch } from "../../actions/searchActions";
import TBody from "../../components/TBody/TBody";
import TInput, { ICONS, KINDS } from "../../components/TInput/TInput";
import TPanel from "../../components/TPanel/TPanel";
import NoSearchResults from "./NoSearchResults/NoSearchResults";
import RecommendedKeywords from "./RecommendedKeywords/RecommendedKeywords";
import css from "./SearchPanel.module.less";
import SearchResults from "./SearchResults/SearchResults";

const ITEMS_PER_PAGE = 9;

export default function SearchPanel() {
  const dispatch = useDispatch();

  const recommandedKeywords = useSelector(
    (state) => state.myPage.recommandedKeywordData.data?.keywords
  );
  const { searchDatas: searchDatas, totalCount: totalCount } = useSelector(
    (state) => state.search
  );
  const {
    theme: themeDatas,
    show: showDatas,
    item: itemDatas,
  } = searchDatas || {};
  const {
    theme: themeCount,
    show: showCount,
    item: itemCount,
  } = totalCount || {};

  const searchPerformed = useSelector((state) => state.search.searchPerformed);

  const [currentPage, setCurrentPage] = useState(1);
  const [paginatedKeywords, setPaginatedKeywords] = useState([]);
  const [pageChanged, setPageChanged] = useState(false);

  const [searchQuery, setSearchQuery] = useState("");

  useEffect(() => {
    dispatch(resetSearch());
  }, [dispatch]);

  useEffect(() => {
    if (recommandedKeywords) {
      const startIndex = (currentPage - 1) * ITEMS_PER_PAGE;
      const endIndex = startIndex + ITEMS_PER_PAGE;

      setPaginatedKeywords(recommandedKeywords.slice(startIndex, endIndex));
    }
  }, [recommandedKeywords, currentPage]);

  useEffect(() => {
    if (pageChanged && paginatedKeywords.length > 0) {
      const firstButtonSpotlightId = "first-keyword-button";

      Spotlight.focus(firstButtonSpotlightId);

      setPageChanged(false);
    }
  }, [pageChanged, paginatedKeywords]);

  const handleSearchChange = useCallback((e) => {
    const query = e.value;

    if (query.length <= 255) {
      setSearchQuery(query);
    }
  }, []);

  const handleSearchSubmit = useCallback(
    (query) => {
      if (query.trim()) {
        dispatch(
          getSearch({
            service: "com.lgshop.app",
            query: query,
            domain: "theme,show,item",
          })
        );
      } else {
        dispatch(resetSearch());
      }
    },
    [dispatch, searchQuery]
  );

  const handleNext = useCallback(() => {
    setCurrentPage((prev) => prev + 1);
    setPageChanged(true);
  }, [currentPage]);

  const handlePrev = useCallback(() => {
    setCurrentPage((prev) => (prev > 1 ? prev - 1 : prev));
    setPageChanged(true);
  }, [currentPage]);

  const hasPrevPage = currentPage > 1;
  const hasNextPage =
    currentPage * ITEMS_PER_PAGE < recommandedKeywords?.length;

  return (
    <TPanel className={css.container}>
      <TBody className={css.tBody}>
        <TInput
          className={css.input}
          autoFocus
          kind={KINDS.withIcon}
          icon={ICONS.search}
          value={searchQuery}
          onChange={handleSearchChange}
          onIconClick={() => handleSearchSubmit(searchQuery)}
        />
        {searchPerformed ? (
          Object.keys(searchDatas).length > 0 ? (
            <SearchResults
              themeDatas={themeDatas}
              itemDatas={itemDatas}
              showDatas={showDatas}
              themeCount={themeCount}
              showCount={showCount}
              itemCount={itemCount}
              query={searchQuery}
            />
          ) : (
            <NoSearchResults />
          )
        ) : (
          <RecommendedKeywords
            keywords={paginatedKeywords}
            onPrev={handlePrev}
            onNext={handleNext}
            hasPrevPage={hasPrevPage}
            hasNextPage={hasNextPage}
            handleSearchSubmit={handleSearchSubmit}
          />
        )}
      </TBody>
    </TPanel>
  );
}
