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

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

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

import { pushPanel, updatePanel } from "../../../../actions/panelActions";
import TButton, { TYPES } from "../../../../components/TButton/TButton";
import TScroller from "../../../../components/TScroller/TScroller";
import useScrollReset from "../../../../hooks/useScrollReset";
import useScrollTo from "../../../../hooks/useScrollTo";
import { panel_names } from "../../../../utils/Config";
import { $L } from "../../../../utils/helperMethods";
import css from "./FeaturedSubCategoryNav.module.less";
import { sendLogFeaturedBrands } from "../../../../actions/logActions";

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

const STRING_CONF = {
  ALL: "ALL",
  MORE: "MORE",
};

const MAX_LENGTH = 20;

export default memo(function FeaturedSubCategoryNav({
  handleItemFocus,
  selectedCategoryLv2Infos,
  selectedCatCdLv2,
  selectedPatncNm,
  setSelectedCatCdLv2,
}) {
  const { getScrollTo, scrollLeft } = useScrollTo();
  const { handleScrollReset, handleStopScrolling } = useScrollReset(
    scrollLeft,
    true
  );

  const dispatch = useDispatch();

  const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo);

  const scrollLeftJob = useRef(new Job((func) => func(), 0));

  useEffect(() => {
    if (!panelInfo?.subCategoryNavX) {
      return;
    }

    const scrollLeftJobValue = scrollLeftJob.current;
    const { subCategoryNavX } = panelInfo;

    scrollLeftJobValue.start(() => scrollLeft({ x: subCategoryNavX }));

    return () => scrollLeftJobValue.stop();
  }, [panelInfo, scrollLeft]);

  const handleBlur = useCallback(
    (itemIndex) => () => {
      if (itemIndex === undefined) {
        handleStopScrolling();
      }
    },
    [handleStopScrolling]
  );

  const handleClick = useCallback(
    (catCdLv2, catNmLv2) => (e) => {
      const tButton = e.currentTarget;

      const xContainer = tButton?.parentNode?.parentNode?.parentNode;

      if (xContainer) {
        const section = "category";
        const subCategoryNavX = xContainer.scrollLeft;

        dispatch(
          updatePanel({
            name: panel_names.FEATURED_BRANDS_PANEL,
            panelInfo: {
              section,
              subCategoryNavX,
              catCdLv2,
            },
          })
        );
      }

      dispatch(sendLogFeaturedBrands({
        catCd: catCdLv2 || "All",
        catNm: catNmLv2 || "All",
        patnrId: panelInfo?.patnrId,
        patncNm: selectedPatncNm,
      }));

      setSelectedCatCdLv2(catCdLv2);
    },
    [
      dispatch,
      panelInfo,
      selectedPatncNm,
      setSelectedCatCdLv2,
    ]
  );

  const handleFocus = useCallback(
    (itemIndex) => () => {
      if (handleItemFocus) {
        handleItemFocus();
      }

      if (itemIndex === undefined) {
        handleScrollReset();
      }
    },
    [handleItemFocus, handleScrollReset]
  );

  const goToSearchPanel = useCallback(() => {
    dispatch(
      pushPanel({
        name: panel_names.SEARCH_PANEL,
      })
    );
  }, [dispatch]);

  const selectedText = !selectedCatCdLv2 ? "Selected " : "";
  const allLabeltext =
    selectedText + "ALL 1 of " + (selectedCategoryLv2Infos.length + 1);

  return (
    <Container className={css.nav}>
      <TScroller
        cbScrollTo={getScrollTo}
        direction="horizontal"
        noScrollByWheel
      >
        <ul>
          <li>
            <TButton
              className={css.tButtonAll}
              color={null}
              onBlur={handleBlur()}
              onClick={handleClick("", "")}
              onFocus={handleFocus()}
              selected={!selectedCatCdLv2}
              size={null}
              type={TYPES.twoDepthCategory}
              ariaLabel={allLabeltext}
              withMarquee
            >
              {$L(STRING_CONF.ALL)}
            </TButton>
          </li>
          {selectedCategoryLv2Infos
            .filter((_, itemIndex) => itemIndex < MAX_LENGTH)
            .map(({ catCdLv2, catNmLv2 }, itemIndex) => (
              <li key={"category-lv2-infos-" + itemIndex}>
                <TButton
                  selected={selectedCatCdLv2 && selectedCatCdLv2 === catCdLv2}
                  size={null}
                  color={null}
                  onBlur={handleBlur(itemIndex)}
                  onClick={handleClick(catCdLv2, catNmLv2)}
                  onFocus={handleFocus(itemIndex)}
                  type={TYPES.twoDepthCategory}
                  ariaLabel={
                    selectedCatCdLv2 && selectedCatCdLv2 === catCdLv2
                      ? "Selected " +
                        catNmLv2 +
                        " " +
                        (itemIndex * 1 + 2) +
                        " of " +
                        (selectedCategoryLv2Infos.length + 1)
                      : "" +
                        catNmLv2 +
                        " " +
                        (itemIndex * 1 + 2) +
                        " of " +
                        (selectedCategoryLv2Infos.length + 1)
                  }
                  withMarquee
                >
                  {catNmLv2}
                </TButton>
              </li>
            ))}
          {selectedCategoryLv2Infos.length > MAX_LENGTH && (
            <li>
              <TButton
                className={css.tButtonMore}
                size={null}
                color={null}
                onClick={goToSearchPanel}
                type={TYPES.twoDepthCategory}
              >
                {$L(STRING_CONF.MORE) + " +"}
              </TButton>
            </li>
          )}
        </ul>
      </TScroller>
    </Container>
  );
});
