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

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

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

export default memo(function SeriesNav({
  brandSeriesInfo,
  fromGNB,
  fromQuickMenu,
  handleItemFocus,
  selectedPatncNm,
  selectedPatnrId,
  selectedSeriesId,
  setSelectedSeriesId,
}) {
  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?.seriesNavX) {
      return;
    }

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

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

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

  useEffect(() => {
    const containerId = "series-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({
          patnrId: selectedPatnrId,
          patncNm: selectedPatncNm,
          srsId: "All",
          srsNm: "All",
        }));
      }, 500);

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

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

  const handleClick = useCallback(
    (seriesId, seriesNm) => (e) => {
      const tButton = e.currentTarget;

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

      if (xContainer) {
        const section = "series";
        const seriesNavX = xContainer.scrollLeft;

        dispatch(
          updatePanel({
            name: panel_names.FEATURED_BRANDS_PANEL,
            panelInfo: {
              section,
              seriesNavX,
              seriesId,
              seriesNm,
            },
          })
        );
      }

      dispatch(sendLogFeaturedBrands({
        patnrId: selectedPatnrId ?? panelInfo?.patnrId,
        patncNm: selectedPatncNm,
        srsId: seriesId,
        srsNm: seriesNm,
      }));

      setSelectedSeriesId(seriesId);
    },
    [
      dispatch,
      panelInfo?.patnrId,
      selectedPatncNm,
      selectedPatnrId,
      setSelectedSeriesId,
    ]
  );

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

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

      if (cursorVisible) {
        return;
      }
    },
    [cursorVisible, handleItemFocus, handleScrollReset]
  );
  const selectedText = !selectedSeriesId ? "Selected " : "";
  const allLabeltext =
    selectedText + "ALL 1 of " + (brandSeriesInfo.length + 1);
  return (
    <Container
      className={css.nav}
      id="series-nav-id"
      spotlightId="series-nav-id"
    >
      <TScroller
        cbScrollTo={getScrollTo}
        direction="horizontal"
        noScrollByWheel
      >
        <ul>
          <li>
            <TButton
              className={!selectedSeriesId && css.selected}
              onBlur={handleBlur()}
              onClick={handleClick(null, null)}
              onFocus={handleFocus()}
              selected={!selectedSeriesId}
              type={TYPES.oneDepthCategory}
              ariaLabel={allLabeltext}
            >
              {$L(STRING_CONF.ALL)}
            </TButton>
          </li>
          {brandSeriesInfo.map(({ seriesId, seriesNm }, index) => (
            <li key={"brand-series-info-" + index}>
              <TButton
                className={
                  selectedSeriesId &&
                  selectedSeriesId === seriesId &&
                  css.selected
                }
                onBlur={handleBlur(index)}
                onClick={handleClick(seriesId, seriesNm)}
                onFocus={handleFocus(index)}
                selected={selectedSeriesId && selectedSeriesId === seriesId}
                type={TYPES.oneDepthCategory}
                ariaLabel={
                  selectedSeriesId && selectedSeriesId === seriesId
                    ? "Selected " +
                      seriesNm +
                      " " +
                      (index * 1 + 2) +
                      " of " +
                      (brandSeriesInfo.length + 1)
                    : "" +
                      seriesNm +
                      " " +
                      (index * 1 + 2) +
                      " of " +
                      (brandSeriesInfo.length + 1)
                }
              >
                {seriesNm}
              </TButton>
            </li>
          ))}
        </ul>
      </TScroller>
    </Container>
  );
});
