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

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

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

import { types } from "../../actions/actionTypes";
import {
  getBrandBestSeller,
  getBrandCategoryInfo,
  getBrandCategoryProductInfo,
  getBrandCreatorsInfo,
  getBrandLayoutInfo,
  getBrandList,
  getBrandLiveChannelInfo,
  getBrandRecommendedShowInfo,
  getBrandSeriesInfo,
  getBrandShowroom,
  getBrandTSVInfo,
} from "../../actions/brandActions";
import { changeAppStatus, setHidePopup } from "../../actions/commonActions";
import {
  sendLogGNB,
  sendLogPartners,
  sendLogTotalRecommend,
} from "../../actions/logActions";
import { setMainLiveUpcomingAlarm } from "../../actions/mainActions";
import {
  deleteMyUpcomingAlertShow,
  getMyUpcomingAlertShow,
  setMyUpcomingUseAlert,
} from "../../actions/myPageActions";
import { updatePanel } from "../../actions/panelActions";
import TBody from "../../components/TBody/TBody";
import TButton, { TYPES } from "../../components/TButton/TButton";
import TPanel from "../../components/TPanel/TPanel";
import TPopUp from "../../components/TPopUp/TPopUp";
import TVerticalPagenator from "../../components/TVerticalPagenator/TVerticalPagenator";
import usePrevious from "../../hooks/usePrevious";
import {
  ACTIVE_POPUP,
  LOG_CONTEXT_NAME,
  LOG_MENU,
  LOG_MESSAGE_ID,
  panel_names,
} from "../../utils/Config";
import { $L } from "../../utils/helperMethods";
import { SpotlightIds } from "../../utils/SpotlightIds";
import Banner from "./Banner/Banner";
import FeaturedBestSeller from "./FeaturedBestSeller/FeaturedBestSeller";
import css from "./FeaturedBrandsPanel.module.less";
import FeaturedCategory from "./FeaturedCategory/FeaturedCategory";
import FeaturedCreators from "./FeaturedCreators/FeaturedCreators";
import LiveChannels from "./LiveChannels/LiveChannels";
import QuickMenu from "./QuickMenu/QuickMenu";
import RecommendedShows from "./RecommendedShows/RecommendedShows";
import Series from "./Series/Series";
import Showroom from "./Showroom/Showroom";
import TodaysDeals from "./TodaysDeals/TodaysDeals";
import UpComing from "./UpComing/UpComing";
import { setContainerLastFocusedElement } from "@enact/spotlight/src/container";
import { sortedIndexOf } from "lodash";

const STRING_CONF = {
  CANCEL: "CANCEL",
  OK: "OK",
  YES: "YES",
  NO_SHOW_MESSAGE: "This show doesn’t exist anymore",
  REMINDER_ON_OFF_MESSAGE:
    "Reminder Notification is turned off. Select Yes to turn on reminders.",
  UPCOMING_TIME_CONFLICT_MESSAGE:
    "A Reminder is already set on the selected schedule. Press OK to overwrite the existing Reminder.",
};

const TEMPLATE_CODE_CONF = {
  LIVE_CHANNELS: "BRD00101",
  UP_COMING: "BRD00102",
  TODAYS_DEALS: "BRD00103",
  BEST_SELLER: "BRD00104",
  RECOMMENDED_SHOWS: "BRD00105",
  FEATURED_CREATORS: "BRD00106",
  SERIES: "BRD00107",
  CATEGORY: "BRD00108",
  SHOWROOM: "BRD00109",
};

const DISPATCH_MAP = Object.freeze({
  [TEMPLATE_CODE_CONF.LIVE_CHANNELS]: getBrandLiveChannelInfo,
  [TEMPLATE_CODE_CONF.TODAYS_DEALS]: getBrandTSVInfo,
  [TEMPLATE_CODE_CONF.BEST_SELLER]: getBrandBestSeller,
  [TEMPLATE_CODE_CONF.RECOMMENDED_SHOWS]: getBrandRecommendedShowInfo,
  [TEMPLATE_CODE_CONF.FEATURED_CREATORS]: getBrandCreatorsInfo,
  [TEMPLATE_CODE_CONF.SERIES]: getBrandSeriesInfo,
  [TEMPLATE_CODE_CONF.CATEGORY]: getBrandCategoryInfo,
  [TEMPLATE_CODE_CONF.SHOWROOM]: getBrandShowroom,
});

const TOP_MARGIN = 36;

const hasTemplateCodeWithValue = (array, value) =>
  array?.some((obj) => obj?.shptmBrndOptTpCd === value) ?? false;

const shouldRenderComponent = (data) => {
  return (
    (Array.isArray(data) && data.length > 0) ||
    (data && typeof data === "object" && Object.keys(data).length > 0)
  );
};

const findSelector = (selector, maxAttempts = 5, currentAttempts = 0) => {
  try {
    if (currentAttempts >= maxAttempts) {
      throw new Error("selector not found");
    }

    const initialSelector = document.querySelector(selector);

    if (initialSelector) {
      return initialSelector;
    } else {
      return findSelector(selector, maxAttempts, currentAttempts + 1);
    }
  } catch (error) {
    console.warn(error.message);
  }
};

const findAndFocusFirstContainer = (timerRef) => {
  if (typeof window === "object") {
    const containers = document.querySelectorAll("[data-wheel-point]");
    const firstContainer = Array.from(containers) //
      .find((container) => container?.getAttribute("data-shelf-order") === "1");

    if (firstContainer) {
      Spotlight.focus(firstContainer);
      clearTimeout(timerRef.current?.timer);
      timerRef.current.timer = null;
      timerRef.current.attemptCount = 0;
      return;
    }

    if (timerRef.current.attemptCount < 5) {
      timerRef.current.attemptCount += 1;
      timerRef.current.timer = setTimeout(
        () => findAndFocusFirstContainer(timerRef),
        200
      );
    }
  }
};

const getMessageByPopupType = (type) => {
  switch (type) {
    case ACTIVE_POPUP.reminderPopup:
      return $L(STRING_CONF.REMINDER_ON_OFF_MESSAGE);
    case ACTIVE_POPUP.timeConflictPopup:
      return $L(STRING_CONF.UPCOMING_TIME_CONFLICT_MESSAGE);
    case ACTIVE_POPUP.noShowPopup:
      return $L(STRING_CONF.NO_SHOW_MESSAGE);
    default:
      return;
  }
};

const getMenuByContainerId = (containerId) => {
  if (!containerId) return;

  const splittedId = containerId.split("-")[0];
  switch (splittedId) {
    case SpotlightIds.BRAND_QUICK_MENU:
      return LOG_MENU.FEATURED_BRANDS_QUICK_MENU;
    case TEMPLATE_CODE_CONF.LIVE_CHANNELS:
      return LOG_MENU.FEATURED_BRANDS_LIVE_CHANNELS;
    case TEMPLATE_CODE_CONF.UP_COMING:
      return LOG_MENU.FEATURED_BRANDS_UPCOMING;
    case TEMPLATE_CODE_CONF.TODAYS_DEALS:
      return LOG_MENU.FEATURED_BRANDS_TODAYS_DEALS;
    case TEMPLATE_CODE_CONF.BEST_SELLER:
      return LOG_MENU.FEATURED_BRANDS_BEST_SELLER;
    case TEMPLATE_CODE_CONF.RECOMMENDED_SHOWS:
      return LOG_MENU.FEATURED_BRANDS_RECOMMENDED_SHOWS;
    case TEMPLATE_CODE_CONF.FEATURED_CREATORS:
      return LOG_MENU.FEATURED_BRANDS_FEATURED_CREATORS;
    case TEMPLATE_CODE_CONF.SERIES:
      return LOG_MENU.FEATURED_BRANDS_SERIES;
    case TEMPLATE_CODE_CONF.CATEGORY:
      return LOG_MENU.FEATURED_BRANDS_CATEGORY;
    case TEMPLATE_CODE_CONF.SHOWROOM:
      return LOG_MENU.FEATURED_BRANDS_SHOWROOM;
    default:
      return;
  }
};

const FeaturedBrandsPanel = ({ isOnTop, panelInfo, spotlightId }) => {
  const dispatch = useDispatch();

  const cursorVisible = useSelector(
    (state) => state.common.appStatus.cursorVisible
  );
  const activePopup = useSelector((state) => state.common.popup.activePopup);
  const popupVisible = useSelector((state) => state.common.popup.popupVisible);
  const brandInfo = useSelector(
    (state) => state.brand.brandInfoData.data.brandInfo
  );
  const brandTopImgInfo = useSelector(
    (state) => state.brand.brandLayoutInfoData.data.brandTopImgInfo
  );
  const brandLayoutInfo = useSelector(
    (state) => state.brand.brandLayoutInfoData.data.brandLayoutInfo
  );
  const brandChanInfo = useSelector(
    (state) => state.brand.brandLiveChannelInfoData.data.brandChanInfo
  );
  const brandChannelCnt = useSelector(
    (state) => state.brand.brandLiveChannelInfoData.data.brandChannelCnt
  );
  const brandLiveChannelUpcoming = useSelector(
    (state) =>
      state.brand.brandLiveChannelInfoData.data.brandLiveChannelUpcoming
  );
  const brandTsvInfo = useSelector(
    (state) => state.brand.brandTsvInfoData.data.brandTsvInfo
  );
  const brandBestSellerInfo = useSelector(
    (state) => state.brand.brandBestSellerData.data.brandBestSellerInfo
  );
  const brandRecommendedShowCategoryInfo = useSelector(
    (state) =>
      state.brand.brandRecommendedShowInfoData.data
        .brandRecommendedShowCategoryInfo
  );
  const brandRecommendedShowInfo = useSelector(
    (state) =>
      state.brand.brandRecommendedShowInfoData.data.brandRecommendedShowInfo
  );
  const brandCreatorsInfo = useSelector(
    (state) => state.brand.brandCreatorsInfoData.data.brandCreatorsInfo
  );
  const barndCreatorsShowInfo = useSelector(
    (state) => state.brand.brandCreatorsInfoData.data.barndCreatorsShowInfo
  );
  const brandSeriesGroupInfo = useSelector(
    (state) => state.brand.brandSeriesInfoData.data.brandSeriesGroupInfo
  );
  const brandSeriesInfo = useSelector(
    (state) => state.brand.brandSeriesInfoData.data.brandSeriesInfo
  );
  const brandCategoryInfo = useSelector(
    (state) => state.brand.brandCategoryInfoData.data.brandCategoryInfo
  );
  const brandCategoryProductInfo = useSelector(
    (state) => state.brand.brandCategoryInfoData.data.brandCategoryProductInfo
  );
  const brandShowroomInfo = useSelector(
    (state) => state.brand.brandShowroomData.data.brandShowroomInfo
  );

  const [displayTopButton, setDisplayTopButton] = useState(false);
  const [focusedContainerId, setFocusedContainerId] = useState(null);
  const [isInitialFocusOccurred, setIsInitialFocusOccurred] = useState(null);
  const [isLogGNBSent, setIsLogGNBSent] = useState(false);
  const [selectedPatncNm, setSelectedPatncNm] = useState(null);
  const [selectedPatnrId, setSelectedPatnrId] = useState(null);
  const [selectedCatCd, setSelectedCatCd] = useState(null);
  const [selectedHstNm, setSelectedHstNm] = useState(null);
  const [selectedSeriesId, setSelectedSeriesId] = useState(null);
  const [selectedCatCdLv1, setSelectedCatCdLv1] = useState(null);
  const [selectedCatCdLv2, setSelectedCatCdLv2] = useState(null);

  const brandInfoRef = usePrevious(brandInfo);
  const displayTopButtonRef = usePrevious(displayTopButton);
  const focusedContainerIdRef = usePrevious(focusedContainerId);

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

  const alarmTimer = useRef(null);
  const cbChangePageRef = useRef(null);
  const lastMenuRef = useRef(null);
  const orderableFlexContainerRef = useRef(null);
  const prevSelectedPatncNmRef = useRef(null);
  const noneTargetTimer = useRef({
    timer: null,
    attemptCount: 0,
  });
  const renderedShelfCountRef = useRef(0);

  const fromDetail = panelInfo?.from && panelInfo.from === "detail";
  const fromGNB = panelInfo?.from && panelInfo.from === "gnb";
  const fromUpcoming = panelInfo?.from && panelInfo.from === "upcoming";
  const fromQuickMenu = panelInfo?.from && panelInfo.from === "menu";

  const hasQuickMenu = useMemo(
    () => brandInfo && brandInfo.length > 1,
    [brandInfo]
  );

  const sortedBrandLayoutInfo = useMemo(
    () => brandLayoutInfo?.sort((a, b) => a.expsOrd - b.expsOrd) ?? [],
    [brandLayoutInfo]
  );

  const doSendLogGNB = useCallback(
    (containerId, shelfOrder) => {
      if (
        !selectedPatncNm ||
        !getMenuByContainerId(containerId) ||
        (getMenuByContainerId(containerId) === lastMenuRef.current &&
          selectedPatncNm === prevSelectedPatncNmRef.current)
      ) {
        return;
      }

      const foundElement = sortedBrandLayoutInfo.find(
        (el) => el.shptmBrndOptTpCd === containerId
      );
      const actualShelfOrder = foundElement ? foundElement.expsOrd : null;

      const selectedBrand = `${LOG_MENU.FEATURED_BRANDS}/${selectedPatncNm}`;
      const currentShelf = `${getMenuByContainerId(containerId)}`;

      const menu =
        selectedBrand && currentShelf && `${selectedBrand} ${currentShelf}`;

      dispatch(
        sendLogTotalRecommend({
          contextName: LOG_CONTEXT_NAME.FEATURED_BRANDS,
          messageId: LOG_MESSAGE_ID.SHELF,
          partner: selectedPatncNm,
          shelfLocation: actualShelfOrder,
          shelfId: containerId,
          shelfTitle: currentShelf,
        })
      );
      dispatch(sendLogGNB(menu));

      setIsLogGNBSent(true);
      prevSelectedPatncNmRef.current = selectedPatncNm;
      lastMenuRef.current = getMenuByContainerId(containerId);
    },
    [selectedPatncNm, sortedBrandLayoutInfo]
  );

  const focusOnMount = useCallback((targetId) => {
    initialFocusTimeoutJob.current.start(() => {
      const focusTarget = findSelector(`[data-spotlight-id="${targetId}"]`);

      if (focusTarget) Spotlight.focus(focusTarget);
      else findAndFocusFirstContainer(noneTargetTimer);
    });
  }, []);

  const handleItemFocus = useCallback(
    (containerId, shelfOrder) => doSendLogGNB(containerId, shelfOrder),
    [doSendLogGNB]
  );

  const handlePopupClick = useCallback(() => {
    if (activePopup?.type === ACTIVE_POPUP.reminderPopup) {
      dispatch(setMyUpcomingUseAlert({ upcomingAlamUseFlag: "Y" }));
    }

    if (activePopup?.type === ACTIVE_POPUP.timeConflictPopup) {
      const { upcomingAlarmInfo, deletedAlertShows } = activePopup;

      dispatch(setMainLiveUpcomingAlarm(upcomingAlarmInfo));
      dispatch(deleteMyUpcomingAlertShow({ showList: deletedAlertShows }));

      alarmTimer.current = setTimeout(
        () => dispatch(getMyUpcomingAlertShow()),
        200
      );
    }

    dispatch(setHidePopup());
    setTimeout(() => Spotlight.focus());
  }, [dispatch, activePopup]);

  const handlePopupClose = useCallback(() => {
    dispatch(setHidePopup());
    setTimeout(() => Spotlight.focus());
  }, [dispatch]);

  const handleTopButtonClick = useCallback(() => {
    if (cbChangePageRef.current) cbChangePageRef.current(0, true);

    let target;

    if (hasQuickMenu) {
      target = document.querySelector(`[data-menu-index="${0}"]`);
    } else {
      const paginatorItem = document.querySelector(`[data-wheel-point]`);
      const spotlightItem = paginatorItem?.querySelector(`[data-spotlight-id]`);
      target = spotlightItem?.querySelector(`[tabindex="${-1}"]`);
    }

    if (target) Spotlight.focus(target);
  }, [hasQuickMenu]);

  const onFocusedContainerId = useCallback(
    (containerId) => setFocusedContainerId(containerId),
    []
  );

  const renderPageItem = useCallback(() => {
    return (
      <>
        {sortedBrandLayoutInfo.map((el, idx) => {
          switch (el.shptmBrndOptTpCd) {
            case TEMPLATE_CODE_CONF.LIVE_CHANNELS: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.LIVE_CHANNELS
                  ) &&
                    shouldRenderComponent(brandChanInfo) && (
                      <LiveChannels
                        brandChanInfo={brandChanInfo}
                        brandChannelCnt={brandChannelCnt}
                        handleItemFocus={handleItemFocus}
                        isOnTop={isOnTop}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        spotlightId={TEMPLATE_CODE_CONF.LIVE_CHANNELS}
                        selectedPatnrId={selectedPatnrId}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.UP_COMING: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.UP_COMING
                  ) &&
                    shouldRenderComponent(brandLiveChannelUpcoming) && (
                      <UpComing
                        brandLiveChannelUpcoming={brandLiveChannelUpcoming}
                        handleItemFocus={handleItemFocus}
                        order={idx + 1}
                        selectedPatnrId={selectedPatnrId}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        spotlightId={TEMPLATE_CODE_CONF.UP_COMING}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.TODAYS_DEALS: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.TODAYS_DEALS
                  ) &&
                    shouldRenderComponent(brandTsvInfo) && (
                      <TodaysDeals
                        brandTsvInfo={brandTsvInfo}
                        handleItemFocus={handleItemFocus}
                        hasQuickMenu={hasQuickMenu}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        spotlightId={TEMPLATE_CODE_CONF.TODAYS_DEALS}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.BEST_SELLER: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.BEST_SELLER
                  ) &&
                    shouldRenderComponent(brandBestSellerInfo) && (
                      <FeaturedBestSeller
                        brandBestSellerInfo={brandBestSellerInfo}
                        handleItemFocus={handleItemFocus}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        spotlightId={TEMPLATE_CODE_CONF.BEST_SELLER}
                        selectedPatnrId={selectedPatnrId}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.RECOMMENDED_SHOWS: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.RECOMMENDED_SHOWS
                  ) &&
                    shouldRenderComponent(brandRecommendedShowCategoryInfo) &&
                    shouldRenderComponent(brandRecommendedShowInfo) && (
                      <RecommendedShows
                        brandRecommendedShowCategoryInfo={
                          brandRecommendedShowCategoryInfo
                        }
                        brandRecommendedShowInfo={brandRecommendedShowInfo}
                        fromGNB={fromGNB}
                        fromQuickMenu={fromQuickMenu}
                        handleItemFocus={handleItemFocus}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        spotlightId={TEMPLATE_CODE_CONF.RECOMMENDED_SHOWS}
                        selectedCatCd={selectedCatCd}
                        selectedPatncNm={selectedPatncNm}
                        selectedPatnrId={selectedPatnrId}
                        setSelectedCatCd={setSelectedCatCd}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.FEATURED_CREATORS: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.FEATURED_CREATORS
                  ) &&
                    shouldRenderComponent(brandCreatorsInfo) &&
                    shouldRenderComponent(barndCreatorsShowInfo) && (
                      <FeaturedCreators
                        brandCreatorsInfo={brandCreatorsInfo}
                        barndCreatorsShowInfo={barndCreatorsShowInfo}
                        fromGNB={fromGNB}
                        fromQuickMenu={fromQuickMenu}
                        handleItemFocus={handleItemFocus}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        selectedHstNm={selectedHstNm}
                        selectedPatncNm={selectedPatncNm}
                        selectedPatnrId={selectedPatnrId}
                        setSelectedHstNm={setSelectedHstNm}
                        spotlightId={TEMPLATE_CODE_CONF.FEATURED_CREATORS}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.SERIES: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.SERIES
                  ) &&
                    shouldRenderComponent(brandSeriesGroupInfo) &&
                    shouldRenderComponent(brandSeriesInfo) && (
                      <Series
                        brandSeriesGroupInfo={brandSeriesGroupInfo}
                        brandSeriesInfo={brandSeriesInfo}
                        fromGNB={fromGNB}
                        fromQuickMenu={fromQuickMenu}
                        handleItemFocus={handleItemFocus}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        spotlightId={TEMPLATE_CODE_CONF.SERIES}
                        selectedPatncNm={selectedPatncNm}
                        selectedPatnrId={selectedPatnrId}
                        selectedSeriesId={selectedSeriesId}
                        setSelectedSeriesId={setSelectedSeriesId}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.CATEGORY: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.CATEGORY
                  ) &&
                    shouldRenderComponent(brandCategoryInfo) &&
                    shouldRenderComponent(brandCategoryProductInfo) && (
                      <FeaturedCategory
                        brandCategoryInfo={brandCategoryInfo}
                        brandCategoryProductInfo={brandCategoryProductInfo}
                        fromGNB={fromGNB}
                        fromQuickMenu={fromQuickMenu}
                        handleItemFocus={handleItemFocus}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        spotlightId={TEMPLATE_CODE_CONF.CATEGORY}
                        selectedCatCdLv1={selectedCatCdLv1}
                        selectedCatCdLv2={selectedCatCdLv2}
                        selectedPatncNm={selectedPatncNm}
                        selectedPatnrId={selectedPatnrId}
                        setSelectedCatCdLv1={setSelectedCatCdLv1}
                        setSelectedCatCdLv2={setSelectedCatCdLv2}
                      />
                    )}
                </React.Fragment>
              );
            }

            case TEMPLATE_CODE_CONF.SHOWROOM: {
              return (
                <React.Fragment key={el.shptmBrndOptTpCd}>
                  {hasTemplateCodeWithValue(
                    sortedBrandLayoutInfo,
                    TEMPLATE_CODE_CONF.SHOWROOM
                  ) &&
                    shouldRenderComponent(brandShowroomInfo) && (
                      <Showroom
                        brandShowroomInfo={brandShowroomInfo}
                        fromGNB={fromGNB}
                        fromQuickMenu={fromQuickMenu}
                        handleItemFocus={handleItemFocus}
                        order={idx + 1}
                        shelfOrder={el.expsOrd}
                        shelfTitle={el.shptmBrndOptTpNm}
                        selectedPatnrId={selectedPatnrId}
                        selectedPatncNm={selectedPatncNm}
                        spotlightId={TEMPLATE_CODE_CONF.SHOWROOM}
                      />
                    )}
                </React.Fragment>
              );
            }
          }
        })}
      </>
    );
  }, [
    brandBestSellerInfo,
    brandCategoryInfo,
    brandCategoryProductInfo,
    brandChanInfo,
    brandChannelCnt,
    brandCreatorsInfo,
    barndCreatorsShowInfo,
    brandLiveChannelUpcoming,
    brandRecommendedShowCategoryInfo,
    brandRecommendedShowInfo,
    brandSeriesGroupInfo,
    brandSeriesInfo,
    brandShowroomInfo,
    brandTsvInfo,
    fromGNB,
    fromQuickMenu,
    handleItemFocus,
    hasQuickMenu,
    isOnTop,
    selectedCatCd,
    selectedCatCdLv1,
    selectedCatCdLv2,
    selectedHstNm,
    selectedPatncNm,
    selectedPatnrId,
    selectedSeriesId,
    sortedBrandLayoutInfo,
  ]);

  const resetStates = useCallback(() => {
    setSelectedCatCd(null);
    setSelectedHstNm(null);
    setSelectedSeriesId(null);
    setSelectedCatCdLv1(null);
    setSelectedCatCdLv2(null);
    setContainerLastFocusedElement(null, ["upcoming-list-id"]);
    setContainerLastFocusedElement(null, ["featured-category-nav-id"]);
  }, []);

  // effect: reset the brand store and set the focusedContainerId and fetch brand list on initial render
  useEffect(() => {
    if (!fromDetail) {
      const containerId =
        fromUpcoming || panelInfo?.linkTpCd === "8002"
          ? TEMPLATE_CODE_CONF.LIVE_CHANNELS
          : SpotlightIds.BRAND_QUICK_MENU;

      setFocusedContainerId(containerId);
      dispatch(getBrandList());
      dispatch({ type: types.RESET_BRAND_STATE_EXCEPT_BRAND_INFO });
    } else setFocusedContainerId(panelInfo?.focusedContainerId);
  }, []);

  // effect: layout information fetching due to partner id change
  useEffect(() => {
    if (!fromDetail) {
      dispatch({ type: types.RESET_BRAND_LAYOUT_INFO });
      dispatch(getBrandLayoutInfo({ patnrId: panelInfo?.patnrId }));
      setIsInitialFocusOccurred(false);
      setDisplayTopButton(false);
    }
  }, [panelInfo?.patnrId]);

  // effect: set selectedPatnrId and selectedPatncNm
  useEffect(() => {
    if (brandInfo) {
      const patnrId = panelInfo?.patnrId;
      const patncNm = brandInfo.find((b) => b?.patnrId === patnrId).patncNm;

      setSelectedPatncNm(patncNm);

      if (!fromDetail) setSelectedPatnrId(patnrId);
    }
  }, [brandInfo, panelInfo?.patnrId]);

  // effect: data fetching based on brandLayoutInfo and selectedPatnrId
  useEffect(() => {
    if (sortedBrandLayoutInfo && selectedPatnrId) {
      Object.entries(DISPATCH_MAP) //
        .forEach(([templateCode, action]) => {
          if (hasTemplateCodeWithValue(sortedBrandLayoutInfo, templateCode)) {
            dispatch(action({ patnrId: selectedPatnrId }));
          }
        });

      resetStates();
    }
  }, [sortedBrandLayoutInfo, selectedPatnrId]);

  useEffect(() => {
    if (selectedCatCd) {
      dispatch(
        getBrandRecommendedShowInfo({
          patnrId: panelInfo?.patnrId,
          catCd: selectedCatCd,
        })
      );
    }
  }, [selectedCatCd]);

  useEffect(() => {
    if (selectedHstNm) {
      dispatch(
        getBrandCreatorsInfo({
          patnrId: panelInfo?.patnrId,
          hstNm: selectedHstNm,
        })
      );
    }
  }, [selectedHstNm]);

  useEffect(() => {
    if (selectedCatCdLv1 === "") {
      dispatch(
        getBrandCategoryInfo({
          patnrId: panelInfo?.patnrId,
        })
      );
      return;
    }

    if (selectedCatCdLv1) {
      dispatch(
        getBrandCategoryProductInfo({
          patnrId: panelInfo?.patnrId,
          catCdLv1: selectedCatCdLv1,
        })
      );
    }
  }, [selectedCatCdLv1]);

  // effect: initial or top panel focus logic
  useEffect(() => {
    if (isOnTop && !isInitialFocusOccurred && selectedPatncNm) {
      // case: gnb or quick menu
      let targetId = "spotlightId-" + panelInfo?.patnrId;

      // case: upcoming or system alarm
      if (fromUpcoming || panelInfo?.linkTpCd === "8002") {
        targetId = TEMPLATE_CODE_CONF.LIVE_CHANNELS;

        if (typeof window === "object" && window.MutationObserver) {
          const observer = new window.MutationObserver((mutations) => {
            for (let idx = mutations.length; idx--; ) {
              if (mutations[idx].addedNodes.length) {
                for (let i = mutations[idx].addedNodes.length; i--; ) {
                  const node = mutations[idx].addedNodes[i];

                  if (node.getAttribute("data-spotlight-id") === targetId) {
                    if (cbChangePageRef.current) {
                      cbChangePageRef.current(targetId, false);
                    }

                    Spotlight.focus(node);
                    break;
                  }
                }
              }
            }
          });

          if (orderableFlexContainerRef.current) {
            observer.observe(orderableFlexContainerRef.current, {
              childList: true,
            });
          }

          return () => observer.disconnect();
        }
      }

      // case: detail
      if (fromDetail) {
        if (panelInfo?.catCdLv1) setSelectedCatCdLv1(panelInfo.catCdLv1);
        if (panelInfo?.catCdLv2) setSelectedCatCdLv2(panelInfo.catCdLv2);
        if (panelInfo?.seriesId) setSelectedSeriesId(panelInfo.seriesId);
      }

      focusOnMount(panelInfo?.lastFocusedTargetId ?? targetId);
      setIsInitialFocusOccurred(true);
    }
  }, [isOnTop, isInitialFocusOccurred, selectedPatncNm]);

  // effect: top button display setting logic
  useEffect(() => {
    if (panelInfo?.displayTopButton) {
      setDisplayTopButton(true);
      return;
    }

    if (typeof window === "object" && window.MutationObserver) {
      const observer = new window.MutationObserver((mutations) => {
        let shouldDisplayTopButton = false;

        for (let idx = mutations.length; idx--; ) {
          if (mutations[idx].type === "childList") {
            renderedShelfCountRef.current =
              orderableFlexContainerRef.current?.children.length || 0;
          }

          if (renderedShelfCountRef.current > 1) {
            shouldDisplayTopButton = true;
            break;
          }
        }

        if (shouldDisplayTopButton !== displayTopButtonRef.current) {
          setDisplayTopButton(shouldDisplayTopButton);
        }
      });

      if (orderableFlexContainerRef.current) {
        observer.observe(orderableFlexContainerRef.current, {
          childList: true,
        });
      }

      return () => observer.disconnect();
    }
  }, [panelInfo?.displayTopButton, panelInfo?.patnrId]);

  // effect: gnb log
  useEffect(() => {
    if (!isOnTop) {
      prevSelectedPatncNmRef.current = null;
      setIsInitialFocusOccurred(false);
    }

    if (focusedContainerId && isOnTop && selectedPatncNm) {
      doSendLogGNB(focusedContainerId);
    }
  }, [doSendLogGNB, focusedContainerId, isOnTop, selectedPatncNm]);

  // effect: partners log
  useEffect(() => {
    if (
      isLogGNBSent &&
      isInitialFocusOccurred &&
      selectedPatnrId &&
      selectedPatncNm
    ) {
      dispatch(
        sendLogPartners({
          patncNm: selectedPatncNm,
          patnrId: selectedPatnrId,
        })
      );
    }
  }, [isLogGNBSent, isInitialFocusOccurred, selectedPatnrId, selectedPatncNm]);

  // effect: unmount
  useEffect(() => {
    return () => {
      dispatch(
        updatePanel({
          name: panel_names.FEATURED_BRANDS_PANEL,
          panelInfo: {
            brandInfo: brandInfoRef.current,
            displayTopButton: displayTopButtonRef.current,
            focusedContainerId: focusedContainerIdRef.current,
            from: "detail",
            lastMenu: lastMenuRef.current,
          },
        })
      );

      clearTimeout(alarmTimer.current);
      clearTimeout(noneTargetTimer.current);
      initialFocusTimeoutJob.current.stop();
    };
  }, []);

  return (
    <TPanel
      className={css.tPanel}
      spotlightId={cursorVisible ? spotlightId : null}
    >
      <TBody
        className={css.tBody}
        scrollable={false}
        spotlightDisabled={!isOnTop}
      >
        <TVerticalPagenator
          cbChangePageRef={cbChangePageRef}
          className={css.tVerticalPagenator}
          defaultContainerId={panelInfo?.focusedContainerId}
          deleteFocus
          onFocusedContainerId={onFocusedContainerId}
          spotlightId={SpotlightIds.BRAND_VERTICAL_PAGENATOR}
          topMargin={TOP_MARGIN}
        >
          {brandInfo && brandInfo.length > 1 && (
            <QuickMenu
              brandInfo={brandInfo}
              fromGNB={fromGNB}
              fromQuickMenu={fromQuickMenu}
              handleItemFocus={handleItemFocus}
              panelPatnrId={panelInfo?.patnrId}
              selectedPatnrId={selectedPatnrId}
              spotlightId={SpotlightIds.BRAND_QUICK_MENU}
              resetStates={resetStates}
            />
          )}

          {brandInfo && brandTopImgInfo && (
            <Banner
              brandInfo={brandInfo}
              brandTopImgInfo={brandTopImgInfo}
              panelPatnrId={panelInfo?.patnrId}
            />
          )}

          {sortedBrandLayoutInfo && (
            <div
              className={css.orderableFlexContainer}
              ref={orderableFlexContainerRef}
            >
              {renderPageItem()}
            </div>
          )}

          {displayTopButton && (
            <TButton
              className={classNames(css.tButton)}
              data-wheel-point
              onClick={handleTopButtonClick}
              size={null}
              spotlightId={SpotlightIds.BRAND_TOP_BUTTON}
              type={TYPES.topButton}
            />
          )}
        </TVerticalPagenator>
      </TBody>

      {(activePopup?.type === ACTIVE_POPUP.reminderPopup ||
        activePopup?.type === ACTIVE_POPUP.timeConflictPopup) && (
        <TPopUp
          button1Text={$L(STRING_CONF.OK)}
          button2Text={$L(STRING_CONF.CANCEL)}
          hasButton
          hasText
          kind="textPopup"
          onClick={handlePopupClick}
          onClose={handlePopupClose}
          open={popupVisible}
          text={getMessageByPopupType(activePopup?.type)}
        />
      )}
    </TPanel>
  );
};

const propsAreEqual = (prev, next) => {
  const keys = Object.keys(prev);
  const nextKeys = Object.keys(next);
  // if (!next.isOnTop) {
  //   //ignore event on background
  //   return true;
  // }
  if (keys.length !== nextKeys.length) {
    return false;
  }
  for (let i = 0; i < keys.length; i++) {
    if (prev[keys[i]] !== next[keys[i]]) {
      return false;
    }
  }
  return true;
};

export default React.memo(FeaturedBrandsPanel, propsAreEqual);
