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

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

import Spotlight from "@enact/spotlight";
import {
  getContainerNavigableElements,
  setContainerLastFocusedElement,
} from "@enact/spotlight/src/container";

import {
  changeAppStatus,
  setDeepLink,
  setExitApp,
  setHidePopup,
  setShowPopup,
} from "../../actions/commonActions";
import { getWelcomeEventInfo } from "../../actions/eventActions";
import {
  checkEnterThroughGNB,
  getHomeLayout,
  getHomeMainContents,
  updateHomeInfo,
} from "../../actions/homeActions";
import { sendLogGNB, sendLogTotalRecommend } from "../../actions/logActions";
import { getSubCategory, getTop20Show } from "../../actions/mainActions";
import { getHomeOnSaleInfo } from "../../actions/onSaleActions";
import { finishVideoPreview } from "../../actions/playActions";
import { getBestSeller } from "../../actions/productActions";
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 useDebugKey from "../../hooks/useDebugKey";
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 BestSeller from "../HomePanel/BestSeller/BestSeller";
import HomeBanner from "../HomePanel/HomeBanner/HomeBanner";
import HomeOnSale from "../HomePanel/HomeOnSale/HomeOnSale";
import css from "../HomePanel/HomePanel.module.less";
import PopularShow from "../HomePanel/PopularShow/PopularShow";
import SubCategory from "../HomePanel/SubCategory/SubCategory";
import EventPopUpBanner from "./EventPopUpBanner/EventPopUpBanner";
import { applyMiddleware } from "redux";

export const TEMPLATE_CODE_CONF = {
  TOP: "DSP00101",
  CATEGORY_ITEM: "DSP00102",
  ON_SALE: "DSP00103",
  POPULAR_SHOW: "DSP00104",
  BEST_SELLER: "DSP00105",
};

const HomePanel = ({ isOnTop }) => {
  const dispatch = useDispatch();

  useDebugKey({ isLandingPage: true });

  const isGnbOpened = useSelector((state) => state.common.isGnbOpened);
  const homeLayoutInfo = useSelector((state) => state.home.layoutData);
  const panelInfo = useSelector(
    (state) => state.home.homeInfo?.panelInfo ?? {}
  );
  const panels = useSelector((state) => state.panels.panels);
  const webOSVersion = useSelector(
    (state) => state.common.appStatus?.webOSVersion
  );
  const enterThroughGNB = useSelector((state) => state.home.enterThroughGNB);
  const defaultFocus = useSelector((state) => state.home.defaultFocus);

  const categoryInfos = useSelector(
    (state) => state.onSale.homeOnSaleData?.data?.categoryInfos
  );

  const categoryItemInfos = useSelector(
    (state) => state.main.subCategoryData?.categoryItemInfos
  );

  const { popupVisible, activePopup } = useSelector(
    (state) => state.common.popup
  );

  const eventPopInfosData = useSelector(
    (state) => state.event.eventData.eventPopInfo
  );
  const eventData = useSelector((state) => state.event.eventData);
  const eventClickSuccess = useSelector(
    (state) => state.event.eventClickSuccess
  );
  const homeOnSaleInfos = useSelector(
    (state) => state.onSale.homeOnSaleData?.data.homeOnSaleInfos
  );
  const bestSellerDatas = useSelector(
    (state) => state.product.bestSellerData?.bestSeller
  );
  const topInfos = useSelector((state) => state.main.top20ShowData.topInfos);
  const isDeepLink = useSelector(
    (state) => state.common.deepLinkInfo.isDeepLink
  );

  const [btnDisabled, setBtnDisabled] = useState(true);
  const [arrowBottom, setArrowBottom] = useState(true);
  const [firstSpot, setFirstSpot] = useState(false);
  const [eventPopOpen, setEventPopOpen] = useState(false);
  const [nowShelf, setNowShelf] = useState(panelInfo.nowShelf);
  const [firstLgCatCd, setFirstLgCatCd] = useState(
    panelInfo.currentCatCd ?? null
  );
  const [cateCd, setCateCd] = useState(panelInfo.currentCatCd ?? null);
  const [cateNm, setCateNm] = useState(panelInfo.currentCateName ?? null);
  const { entryMenu, nowMenu } = useSelector((state) => state.common.menu);
  const [focusedContainerId, setFocusedContainerId] = useState(
    panelInfo.focusedContainerId
  );

  const isInitialRender = useRef(true);
  const verticalPagenatorRef = useRef(null);
  const currentSentMenuRef = useRef(null);

  useEffect(() => {
    if (nowMenu === "Home/Top") {
      dispatch(
        sendLogTotalRecommend({
          messageId: LOG_MESSAGE_ID.HOME,
          contextName: LOG_CONTEXT_NAME.HOME,
        })
      );
    }
  }, [entryMenu, nowMenu]);

  const sortedHomeLayoutInfo = useMemo(() => {
    if (homeLayoutInfo && homeLayoutInfo.homeLayoutInfo) {
      const sorted = [...homeLayoutInfo.homeLayoutInfo].sort(
        (x, y) => x.expsOrd - y.expsOrd
      );
      return sorted;
    }
    return [];
  }, [homeLayoutInfo]);

  const pageSpotIds = useMemo(() => {
    const spots = [];
    for (let i = 0; i < sortedHomeLayoutInfo.length; i++) {
      spots.push(sortedHomeLayoutInfo[i].shptmApphmDspyOptCd);
    }
    return spots;
  }, [sortedHomeLayoutInfo]);

  const cbChangePageRef = useRef(null);

  const loadingComplete = useSelector((state) => state.common?.loadingComplete);

  const onCancel = useCallback(() => {
    const currentSpot = Spotlight.getCurrent();

    if (!isOnTop) {
      return;
    }
    if (isGnbOpened) {
      return;
    }
    dispatch(
      updateHomeInfo({
        name: panel_names.HOME_PANEL,
        panelInfo: {
          currentSpot: currentSpot,
        },
      })
    );

    dispatch(setShowPopup(ACTIVE_POPUP.exitPopup));
  }, [isOnTop, isGnbOpened, dispatch]);

  const onExit = useCallback(() => {
    dispatch(setExitApp());

    dispatch(
      sendLogTotalRecommend({
        contextName: LOG_CONTEXT_NAME.SHOPTIME,
        messageId: LOG_MESSAGE_ID.VIEW_CHANGE,
        visible: false,
      })
    );
  }, [dispatch]);

  const onClose = useCallback(() => {
    dispatch(setHidePopup());
    setTimeout(() => {
      Spotlight.focus(SpotlightIds.HOME_TBODY);
    }, 0);
  }, [dispatch]);

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

    if (sortedHomeLayoutInfo?.[0]) {
      const containerId = sortedHomeLayoutInfo[0].shptmApphmDspyOptCd;
      const navigableEls = getContainerNavigableElements(containerId);
      const navigableIds = navigableEls.filter((el) => typeof el === "string");
      const target =
        containerId === TEMPLATE_CODE_CONF.TOP ? "banner0" : containerId;

      if (navigableIds.length > 0) {
        setContainerLastFocusedElement(null, navigableIds);
      }

      setContainerLastFocusedElement(null, [containerId]);
      setTimeout(() => Spotlight.focus(target));
    }
  }, [sortedHomeLayoutInfo]);

  const doSendLogGNB = useCallback(
    (containerId, location = null, title = null) => {
      let nowMenu;
      switch (containerId) {
        case TEMPLATE_CODE_CONF.TOP:
          nowMenu = LOG_MENU.HOME_TOP;
          break;
        case TEMPLATE_CODE_CONF.CATEGORY_ITEM:
          nowMenu = LOG_MENU.HOME_CATEGORY;
          break;
        case TEMPLATE_CODE_CONF.ON_SALE:
          nowMenu = LOG_MENU.HOME_ON_SALE;
          break;
        case TEMPLATE_CODE_CONF.POPULAR_SHOW:
          nowMenu = LOG_MENU.HOME_POPULAR_SHOWS;
          break;
        case TEMPLATE_CODE_CONF.BEST_SELLER:
          nowMenu = LOG_MENU.HOME_BEST_SELLER;
          break;
        default:
          nowMenu = LOG_MENU.HOME_TOP;
          break;
      }

      if (containerId !== nowShelf && location && title) {
        dispatch(
          sendLogTotalRecommend({
            contextName: LOG_CONTEXT_NAME.HOME,
            messageId: LOG_MESSAGE_ID.SHELF,
            shelfLocation: location,
            shelfId: containerId,
            shelfTitle: title,
          })
        );

        setNowShelf(containerId);
      }
      if (nowMenu && nowMenu !== currentSentMenuRef.current) {
        dispatch(sendLogGNB(nowMenu));
        currentSentMenuRef.current = nowMenu;
      }
    },
    [pageSpotIds, nowShelf, panelInfo.nowShelf]
  );

  const handleItemFocus = useCallback(
    (containerId, location, title) => () => {
      doSendLogGNB(containerId, location, title);
    },
    [doSendLogGNB]
  );

  const renderPageItem = useCallback(() => {
    return (
      <>
        {sortedHomeLayoutInfo.map((el) => {
          switch (el.shptmApphmDspyOptCd) {
            case TEMPLATE_CODE_CONF.TOP: {
              return (
                <HomeBanner
                  key={el.shptmApphmDspyOptCd}
                  spotlightId={el.shptmApphmDspyOptCd}
                  firstSpot={
                    !panelInfo.focusedContainerId && !panelInfo.currentSpot
                  }
                  className={css.homeBannerWrap}
                  handleShelfFocus={handleItemFocus(
                    el.shptmApphmDspyOptCd,
                    el.expsOrd,
                    el.shptmApphmDspyOptNm
                  )}
                  handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
                />
              );
            }
            case TEMPLATE_CODE_CONF.CATEGORY_ITEM: {
              if (
                categoryInfos &&
                categoryInfos.length > 0 &&
                categoryItemInfos?.subCatItemList &&
                categoryItemInfos.subCatItemList.length > 0
              ) {
                return (
                  <SubCategory
                    key={el.shptmApphmDspyOptCd}
                    spotlightId={el.shptmApphmDspyOptCd}
                    catCd={cateCd}
                    cateNm={cateNm}
                    handleShelfFocus={handleItemFocus(
                      el.shptmApphmDspyOptCd,
                      el.expsOrd,
                      el.shptmApphmDspyOptNm
                    )}
                    handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
                    shelfLocation={el.expsOrd}
                    shelfTitle={el.shptmApphmDspyOptNm}
                  />
                );
              } else break;
            }
            case TEMPLATE_CODE_CONF.ON_SALE: {
              if (homeOnSaleInfos && homeOnSaleInfos.length > 0) {
                return (
                  <HomeOnSale
                    key={el.shptmApphmDspyOptCd}
                    spotlightId={el.shptmApphmDspyOptCd}
                    handleShelfFocus={handleItemFocus(
                      el.shptmApphmDspyOptCd,
                      el.expsOrd,
                      el.shptmApphmDspyOptNm
                    )}
                    handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
                    shelfLocation={el.expsOrd}
                    shelfTitle={el.shptmApphmDspyOptNm}
                  />
                );
              } else break;
            }
            case TEMPLATE_CODE_CONF.POPULAR_SHOW: {
              if (topInfos && topInfos.length > 0) {
                return (
                  <PopularShow
                    key={el.shptmApphmDspyOptCd}
                    spotlightId={el.shptmApphmDspyOptCd}
                    handleShelfFocus={handleItemFocus(
                      el.shptmApphmDspyOptCd,
                      el.expsOrd,
                      el.shptmApphmDspyOptNm
                    )}
                    handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
                    shelfLocation={el.expsOrd}
                    shelfTitle={el.shptmApphmDspyOptNm}
                  />
                );
              } else break;
            }
            case TEMPLATE_CODE_CONF.BEST_SELLER: {
              if (bestSellerDatas && bestSellerDatas.length > 0) {
                return (
                  <BestSeller
                    key={el.shptmApphmDspyOptCd}
                    spotlightId={el.shptmApphmDspyOptCd}
                    handleShelfFocus={handleItemFocus(
                      el.shptmApphmDspyOptCd,
                      el.expsOrd,
                      el.shptmApphmDspyOptNm
                    )}
                    handleItemFocus={handleItemFocus(el.shptmApphmDspyOptCd)}
                    shelfLocation={el.expsOrd}
                    shelfTitle={el.shptmApphmDspyOptNm}
                  />
                );
              } else break;
            }
          }
        })}
        {loadingComplete &&
          sortedHomeLayoutInfo &&
          sortedHomeLayoutInfo.length > 0 && (
            <TButton
              className={css.tButton}
              onClick={handleTopButtonClick}
              size={null}
              type={TYPES.topButton}
              spotlightId={"home-top-btn"}
              spotlightDisabled={btnDisabled}
              data-wheel-point={true}
              aria-label="Move to Top, Button"
            />
          )}
      </>
    );
  }, [
    sortedHomeLayoutInfo,
    cateCd,
    cateNm,
    handleItemFocus,
    handleTopButtonClick,
    btnDisabled,
    panelInfo.focusedContainerId,
    panelInfo.currentSpot,
    categoryItemInfos,
    categoryInfos,
    homeOnSaleInfos,
    bestSellerDatas,
    topInfos,
  ]);

  const _onScrollStatusChanged = useCallback((status) => {
    if (status === "end") {
      setArrowBottom(false);
    } else {
      setArrowBottom(true);
    }
  }, []);

  const _onScroll = (e) => {
    if (e.scrollTop !== 0) {
      dispatch(finishVideoPreview());
    }
  };

  const _onFocusedContainerId = useCallback(
    (containerId) => {
      setFocusedContainerId(containerId);
      if (enterThroughGNB && cbChangePageRef.current && !isOnTop) {
        Spotlight.resume();
        cbChangePageRef.current(0, false);
        Spotlight.focus(defaultFocus);
        setBtnDisabled(false);
        dispatch(checkEnterThroughGNB(false));

        return;
      }

      if (!firstSpot) {
        setTimeout(() => {
          Spotlight.resume();
          setFirstSpot(true);
          if (Spotlight.getPointerMode()) {
            dispatch(finishVideoPreview());
          }
          if (panelInfo.currentCatCd) {
            Spotlight.focus("spotlightId-" + panelInfo.currentCatCd);
          }
          if (panelInfo.currentSpot) {
            Spotlight.focus(panelInfo.currentSpot);
          }
          // }

          //exit popup case
          Spotlight.focus(SpotlightIds.TPOPUP);
          setBtnDisabled(false);
        }, 0);
      }
    },
    [
      panelInfo,
      firstSpot,
      enterThroughGNB,
      defaultFocus,
      cbChangePageRef,
      dispatch,
      isOnTop,
    ]
  );

  const bestSellerLoaded = useCallback(() => {
    dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
  }, []);

  useEffect(() => {
    if (isInitialRender.current) {
      isInitialRender.current = false;

      if (isDeepLink || (!panels.length && !panelInfo.focusedContainerId)) {
        dispatch(
          changeAppStatus({ showLoadingPanel: { show: true, type: "wait" } })
        );
        dispatch(getHomeMainContents());
        dispatch(getHomeLayout());
        dispatch(
          getHomeOnSaleInfo({
            homeSaleInfosIncFlag: "Y",
            categoryIncFlag: "Y",
            saleInfosIncFlag: "N",
          })
        );
        dispatch(getTop20Show());
        dispatch(getBestSeller(bestSellerLoaded));

        if (isDeepLink) {
          dispatch(setDeepLink({ contentTarget: "", isDeepLink: false }));
        }
      }
    }
  }, [dispatch, isDeepLink, panels.length, panelInfo.focusedContainerId]);

  useEffect(() => {
    doSendLogGNB(focusedContainerId);
  }, [focusedContainerId]);

  useEffect(() => {
    if (firstLgCatCd === null) {
      if (categoryInfos) {
        setFirstLgCatCd(categoryInfos[0]?.lgCatCd);
        setCateCd(categoryInfos[0]?.lgCatCd);
        setCateNm(categoryInfos[0]?.lgCatNm);
      }
    }
    if (firstLgCatCd !== null) {
      dispatch(
        getSubCategory(
          {
            lgCatCd: firstLgCatCd, //LG Electronics Base
            pageSize: 10,
            tabType: "CAT00102",
            filterType: "CAT00202",
          },
          1
        )
      );
    }
  }, [categoryInfos, firstLgCatCd, dispatch]);

  const checkBillngEvent = useCallback(
    (eventTpCd) => {
      if (webOSVersion && Number(webOSVersion) >= 4) {
        if (eventTpCd === "EVT00108" || eventTpCd === "EVT00107") {
          if (webOSVersion && Number(webOSVersion) >= 6) {
            setEventPopOpen(true);
          } else setEventPopOpen(false);
        } else setEventPopOpen(true);
      } else setEventPopOpen(false);
    },
    [webOSVersion]
  );

  useEffect(() => {
    if (Object.keys(eventData).length >= 1) {
      if (eventPopInfosData && eventClickSuccess === null) {
        checkBillngEvent(eventPopInfosData.evntTpCd);
        if (eventPopOpen) {
          dispatch(setShowPopup(ACTIVE_POPUP.eventPopup));
        }
      }
    }
  }, [eventPopOpen, eventData]);

  useEffect(() => {
    if (Object.keys(eventData).length <= 0 && eventClickSuccess === null) {
      dispatch(getWelcomeEventInfo());
    }
  }, [dispatch]);

  useEffect(() => {
    if (
      isOnTop &&
      panelInfo?.lastFocusedTargetId &&
      !panelInfo?.focusedContainerId
    ) {
      Spotlight.focus(panelInfo.lastFocusedTargetId);
    }
  }, [isOnTop, panelInfo?.lastFocusedTargetId, panelInfo?.focusedContainerId]);

  useEffect(() => {
    return () => {
      const c = Spotlight.getCurrent();
      let targetSpotlightId = null;
      let targetSpotlightCatcd = null;
      let targetSpotlightCateNm = null;
      if (c) {
        targetSpotlightId = c.getAttribute("data-spotlight-id");
        targetSpotlightCatcd = c.getAttribute("data-catcd-num");
        targetSpotlightCateNm = c.getAttribute("data-catcd-nm");
      }

      const tBody = document.querySelector(
        `[data-spotlight-id="${SpotlightIds.HOME_TBODY}"]`
      );
      const currentSpot = c && tBody.contains(c) ? targetSpotlightId : null;

      dispatch(checkEnterThroughGNB(false));
      dispatch(
        updateHomeInfo({
          name: panel_names.HOME_PANEL,
          panelInfo: {
            currentSpot: currentSpot,
            currentCatCd: targetSpotlightCatcd,
            currentCateName: targetSpotlightCateNm,
            focusedContainerId: focusedContainerId,
          },
        })
      );
    };
  }, [dispatch, focusedContainerId]);

  const handleArrowClick = useCallback(() => {
    if (verticalPagenatorRef.current) {
      const nextNode = verticalPagenatorRef.current.findNextWheelPoint();
      if (nextNode) {
        verticalPagenatorRef.current.moveToNode(nextNode, true, true);
      }
    }
  }, [verticalPagenatorRef]);

  return (
    <>
      <TPanel className={css.panel} onCancel={onCancel}>
        {homeLayoutInfo && (
          <TBody
            spotlightId={SpotlightIds.HOME_TBODY}
            className={css.tBody}
            scrollable={false}
            spotlightDisabled={!isOnTop}
          >
            <TVerticalPagenator
              ref={verticalPagenatorRef}
              className={css.tVerticalPagenator}
              spotlightId={"home_verticalPagenator"}
              defaultContainerId={panelInfo.focusedContainerId}
              disabled={!isOnTop}
              onScrollStatusChanged={_onScrollStatusChanged}
              onFocusedContainerId={_onFocusedContainerId}
              cbChangePageRef={cbChangePageRef}
              topMargin={36}
              onScroll={_onScroll}
            >
              {renderPageItem()}
            </TVerticalPagenator>
          </TBody>
        )}

        {arrowBottom && (
          <p
            className={classNames(css.arrow, css.arrowBottom)}
            onClick={handleArrowClick}
          />
        )}

        {activePopup === ACTIVE_POPUP.exitPopup && (
          <TPopUp
            kind="exitPopup"
            open={popupVisible}
            onExit={onExit}
            onClose={onClose}
            hasButton
            button1Text={$L("Exit")}
            button2Text={$L("Cancel")}
            hasText
            title={$L("Exit Shop Time")}
            text={$L("Are you sure you want to exit Shop Time?")}
          />
        )}
        {(activePopup === ACTIVE_POPUP.eventPopup ||
          activePopup === ACTIVE_POPUP.smsPopup) && <EventPopUpBanner />}
      </TPanel>
    </>
  );
};

export default HomePanel;
