import React, { useCallback, useEffect, useMemo, useRef } from "react";

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

import { Job } from "@enact/core/util";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";

import { continueSearch } from "../../../actions/searchActions";
import SectionTitle from "../../../components/SectionTitle/SectionTitle";
import TVirtualGridList from "../../../components/TVirtualGridList/TVirtualGridList";
import usePrevious from "../../../hooks/usePrevious";
import useScrollTo from "../../../hooks/useScrollTo";
import { SEARCH_DATA_MAX_RESULTS_LIMIT } from "../../../utils/Config";
import { SpotlightIds } from "../../../utils/SpotlightIds";
import SearchItemCard from "./SearchCard/SearchItemCard";
import SearchShowCard from "./SearchCard/SearchShowCard";
import SearchThemeCard from "./SearchCard/SearchThemeCard";
import css from "./SearchResultsType.module.less";

const Container = SpotlightContainerDecorator(
  { leaveFor: { right: "" }, enterTo: "last-focused" },
  "div"
);

const ITEM_SIZE = {
  theme: {
    itemWidth: 560,
    itemHeight: 130,
    spacing: 30,
  },

  show: {
    itemWidth: 348,
    itemHeight: 264,
    spacing: 6,
  },

  item: {
    itemWidth: 561,
    itemHeight: 150,
    spacing: 30,
  },
};

export default function SearchResultsType({
  category,
  count,
  data,
  idx,
  panelInfo,
  searchQueryRef,
  sectionTitle,
}) {
  const dispatch = useDispatch();
  const { getScrollTo, scrollLeft } = useScrollTo();
  const searchAppendJob = useRef(new Job((func) => func(), 1000));
  const dataRef = usePrevious(data);
  const searchTimestamp = useSelector((state) => state.search.searchTimestamp);

  useEffect(() => {
    if (data && !panelInfo.currentSpot) {
      scrollLeft();
    }
  }, [data]);

  const onScroll = useCallback(
    (ev) => {
      const { lastVisibleIndex } = ev.moreInfo;
      if (
        dataRef.current &&
        dataRef.current.length >= SEARCH_DATA_MAX_RESULTS_LIMIT
      ) {
        const nextSearchIndex =
          (Math.floor(lastVisibleIndex / SEARCH_DATA_MAX_RESULTS_LIMIT) + 1) *
            SEARCH_DATA_MAX_RESULTS_LIMIT +
          1;
        if (!dataRef.current[nextSearchIndex]) {
          searchAppendJob.current.throttle(() => {
            dispatch(continueSearch(category, nextSearchIndex));
          });
        }
      }
    },
    [category, count]
  );

  const renderItem = useCallback(
    ({ index, ...rest }) => {
      const targetItem = data[index] ? data[index] : {};
      switch (category) {
        case "theme": {
          const {
            contentId,
            // endTime,
            keyword,
            // partnerLogo,
            partnerName,
            // startTime,
            title,
          } = targetItem;

          return (
            <SearchThemeCard
              contentId={contentId}
              idx={idx}
              key={category + index}
              keyword={keyword}
              patncNm={partnerName}
              searchQueryRef={searchQueryRef}
              spotlightId={SpotlightIds.SEARCH_THEME + index}
              title={title}
              {...rest}
            />
          );
        }

        case "show": {
          const {
            contentId,
            // endTime,
            liveFlag,
            // partnerId,
            // partnerLogo,
            partnerName,
            // startTime,
            thumbnail,
            title,
          } = targetItem;

          return (
            <SearchShowCard
              contentId={contentId}
              idx={idx}
              key={category + index}
              liveFlag={liveFlag}
              patncNm={partnerName}
              searchQueryRef={searchQueryRef}
              spotlightId={SpotlightIds.SEARCH_SHOW + index}
              thumbnail={thumbnail}
              title={title}
              {...rest}
            />
          );
        }

        case "item": {
          const {
            contentId,
            dcPrice,
            // partnerLogo,
            partnerName,
            price,
            // reviewGrade,
            // soldout,
            thumbnail,
            dataSize,
            title,
          } = targetItem;
          return (
            <SearchItemCard
              contentId={contentId}
              dcPrice={dcPrice}
              idx={idx}
              key={category + index}
              patncNm={partnerName}
              price={price}
              searchQueryRef={searchQueryRef}
              spotlightId={SpotlightIds.SEARCH_ITEM + index}
              thumbnail={thumbnail}
              title={title}
              length={dataSize}
              {...rest}
            />
          );
        }

        default:
          return;
      }
    },
    [category, data, idx, searchQueryRef]
  );

  const gridListId = useMemo(() => {
    switch (category) {
      case "theme":
        return `${SpotlightIds.SEARCH_THEME}-${searchTimestamp}`;
      case "show":
        return `${SpotlightIds.SEARCH_SHOW}-${searchTimestamp}`;
      case "item":
        return `${SpotlightIds.SEARCH_ITEM}-${searchTimestamp}`;
    }
  }, [category, searchTimestamp]);

  const { itemWidth, itemHeight, spacing } = ITEM_SIZE[category] || {};

  return (
    <Container
      data-wheel-point={true}
      spotlightId={"searchresult_section_" + category + searchTimestamp}
    >
      <SectionTitle
        className={css.sectionTitle}
        title={sectionTitle}
        itemCount={count ? count : null}
        label={sectionTitle + ", Heading 2"}
      />
      <TVirtualGridList
        defaultSpotlightId={panelInfo.currentSpot}
        restorePositionX={panelInfo.x}
        spotlightId={gridListId}
        key={`${category}-${searchTimestamp}`}
        cbScrollTo={getScrollTo}
        className={classNames(
          css.container,
          category && css[category],
          css.grid
        )}
        dataSize={count ? count : 0}
        renderItem={renderItem}
        direction="horizontal"
        itemWidth={itemWidth}
        itemHeight={itemHeight}
        spacing={spacing}
        onScroll={onScroll}
      />
    </Container>
  );
}
