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 {
  getContainerId,
  setContainerLastFocusedElement,
} from '@enact/spotlight/src/container';

import { sendLogFeaturedBrands } from '../../../../actions/logActions';
import { 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 './FeaturedCategoryNav.module.less';

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

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

export default memo(function FeaturedCategoryNav({
  brandCategoryInfo,
  fromGNB,
  fromQuickMenu,
  handleItemFocus,
  selectedCatCdLv1,
  selectedPatncNm,
  selectedPatnrId,
  setSelectedCatCdLv1,
  setSelectedCatCdLv2,
}) {
  const { getScrollTo, scrollLeft } = useScrollTo();
  const { handleScrollReset, handleStopScrolling } = useScrollReset(
    scrollLeft,
    true
  );
  const dispatch = useDispatch();

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

  const cursorVisible = useSelector(
    (state) => state.common.appStatus.cursorVisible
  );

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

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

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

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

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

  useEffect(() => {
    const containerId = "featured-category-nav-id";
    const container = document.getElementById(containerId);

    if (container) {
      const childrenId = getContainerId(container?.children[0].children[0]);

      if (childrenId) {
        setContainerLastFocusedElement(null, [containerId, childrenId]);
      }
    }

    scrollLeft();
  }, [scrollLeft, selectedPatnrId]);

  useEffect(() => {
    if (fromGNB || fromQuickMenu) {
      logTimerRef.current = setTimeout(() => {
        dispatch(
          sendLogFeaturedBrands({
            catCd: "All",
            catNm: "All",
            patnrId: selectedPatnrId,
            patncNm: selectedPatncNm,
          })
        );
      }, 500);

      return () => clearTimeout(logTimerRef.current);
    }
  }, [fromGNB, fromQuickMenu, selectedPatncNm, selectedPatnrId]);

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

  const handleClick = useCallback(
    (catCdLv1, catNmLv1) => (e) => {
      const tButton = e.currentTarget;

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

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

        dispatch(
          updatePanel({
            name: panel_names.FEATURED_BRANDS_PANEL,
            panelInfo: {
              section,
              categoryNavX,
              catCdLv1,
              catCdLv2: null,
              x: 0,
            },
          })
        );
      }

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

      setSelectedCatCdLv1(catCdLv1);
      setSelectedCatCdLv2(null);
    },
    [
      dispatch,
      panelInfo?.patnrId,
      selectedPatncNm,
      selectedPatnrId,
      setSelectedCatCdLv1,
      setSelectedCatCdLv2,
    ]
  );

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

      if (itemIndex === undefined) {
        handleScrollReset();
      }

      if (cursorVisible) {
        return;
      }
    },
    [cursorVisible, handleItemFocus, handleScrollReset]
  );
  const selectedText = !selectedCatCdLv1 ? "Selected " : "";
  const allLabeltext =
    selectedText + "ALL 1 of " + (brandCategoryInfo.length + 1);

  return (
    <Container
      className={css.nav}
      id="featured-category-nav-id"
      spotlightId="featured-category-nav-id"
    >
      <TScroller
        cbScrollTo={getScrollTo}
        direction="horizontal"
        noScrollByWheel
      >
        <ul>
          <li>
            <TButton
              className={!selectedCatCdLv1 && css.selected}
              onBlur={handleBlur()}
              onClick={handleClick("", "")}
              onFocus={handleFocus()}
              selected={!selectedCatCdLv1}
              type={TYPES.oneDepthCategory}
              ariaLabel={allLabeltext}
            >
              {$L(STRING_CONF.ALL)}
            </TButton>
          </li>
          {brandCategoryInfo.map(({ catCdLv1, catNmLv1 }, itemIndex) => (
            <li key={"brand-category-info-" + catCdLv1}>
              <TButton
                className={
                  selectedCatCdLv1 &&
                  selectedCatCdLv1 === catCdLv1 &&
                  css.selected
                }
                onBlur={handleBlur(itemIndex)}
                onClick={handleClick(catCdLv1, catNmLv1)}
                onFocus={handleFocus(itemIndex)}
                selected={selectedCatCdLv1 && selectedCatCdLv1 === catCdLv1}
                type={TYPES.oneDepthCategory}
                ariaLabel={
                  selectedCatCdLv1 && selectedCatCdLv1 === catCdLv1
                    ? "Selected " +
                      catNmLv1 +
                      " " +
                      (itemIndex * 1 + 2) +
                      " of " +
                      (brandCategoryInfo.length + 1)
                    : "" +
                      catNmLv1 +
                      " " +
                      (itemIndex * 1 + 2) +
                      " of " +
                      (brandCategoryInfo.length + 1)
                }
              >
                {catNmLv1}
              </TButton>
            </li>
          ))}
        </ul>
      </TScroller>
    </Container>
  );
});
