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

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

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

import { types } from "../../actions/actionTypes";
import { changeAppStatus } from "../../actions/commonActions";
import {
  sendLogCuration,
  sendLogGNB,
  sendLogTotalRecommend,
} from "../../actions/logActions";
import { copyCategoryInfos, getOnSaleInfo } from "../../actions/onSaleActions";
import { popPanel, updatePanel } from "../../actions/panelActions";
import TBody from "../../components/TBody/TBody";
import TButton, { TYPES } from "../../components/TButton/TButton";
import { removeDotAndColon } from "../../components/TItemCard/TItemCard";
import TPanel from "../../components/TPanel/TPanel";
import TVerticalPagenator from "../../components/TVerticalPagenator/TVerticalPagenator";
import { LOG_MENU, LOG_TP_NO, panel_names } from "../../utils/Config";
import OnSaleContents from "./OnSaleContents/OnSaleContents";
import OnSaleNav from "./OnSaleNav/OnSaleNav";
import css from "./OnSalePanel.module.less";
import { updateHomeInfo } from "../../actions/homeActions";

const getExpsOrdByLgCatCd = (array, value) => {
  const expsOrd = array.findIndex(({ lgCatCd }) => value === lgCatCd) + 1;
  return expsOrd.toString();
};

export default function OnSalePanel({ panelInfo, spotlightId }) {
  const dispatch = useDispatch();

  const categoryInfos = useSelector(
    (state) => state.onSale.onSaleData.data.categoryInfos
  );
  const copiedCategoryInfos = useSelector(
    (state) => state.onSale.copiedCategoryInfos
  );
  const saleInfos = useSelector(
    (state) => state.onSale.onSaleData.data.saleInfos
  );

  const [categories, setCategories] = useState();
  const [firstFocusableTarget, setFirstFocusableTarget] = useState();
  const [isInitialFocusOccurred, setIsInitialFocusOccurred] = useState(false);
  const [isInitialRendered, setIsInitialRendered] = useState(true);
  const [isReadyForInitialFocusTarget, setIsReadyForInitialFocusTarget] =
    useState(false);
  const [isTopButtonClicked, setIsTopButtonClicked] = useState(false);
  const [selectedLgCatCd, setSelectedLgCatCd] = useState();
  const [selectedLgCatNm, setSelectedLgCatNm] = useState();
  const [spotlightDisabled, setSpotlightDisabled] = useState(true);
  const [currentFocusedShelf, setCurrentFocusedShelf] = useState(null);

  const enteredThroughEventPopup = Object.keys(panelInfo).length === 1;
  const enteredThroughGNB = Object.keys(panelInfo).length === 0;
  const previousPanelIsHome = panelInfo?.nowShelf !== undefined;
  const previousPanelIsDetail = panelInfo?.noResetFlag === true;

  const cbChangePageRef = useRef(null);
  const focusedContainerIdRef = useRef(0);
  const initialFocusTimeoutJob = useRef(new Job((func) => func(), 0));
  const timerRef = useRef(null);

  useEffect(() => {
    dispatch(sendLogGNB(LOG_MENU.ON_SALE));
  }, []);

  useEffect(() => {
    if (!panelInfo?.noResetFlag) {
      dispatch({ type: types.RESET_ON_SALE_STATE });
    }
  }, [dispatch, panelInfo?.noResetFlag]);

  useEffect(() => {
    if (isInitialRendered) {
      if (previousPanelIsDetail) {
        setIsInitialRendered(false);
        return;
      }

      let props = { categoryIncFlag: "Y", saleInfosIncFlag: "Y" };

      if (previousPanelIsHome || enteredThroughEventPopup) {
        props = { ...props, lgCatCd: panelInfo?.lgCatCd };
      }

      dispatch(getOnSaleInfo(props));
      setIsInitialRendered(false);
    }
  }, [
    enteredThroughEventPopup,
    isInitialRendered,
    panelInfo?.lgCatCd,
    previousPanelIsDetail,
    previousPanelIsHome,
  ]);

  useEffect(() => {
    if (!categories) {
      if (previousPanelIsDetail) {
        setCategories(copiedCategoryInfos);
        return;
      }
      if (categoryInfos) {
        dispatch(copyCategoryInfos(categoryInfos));
        setCategories(categoryInfos);
        setSelectedLgCatCd(panelInfo?.lgCatCd);
        setSelectedLgCatNm(panelInfo?.lgCatNm);
      }
    }
  }, [
    categories,
    categoryInfos,
    copiedCategoryInfos,
    previousPanelIsDetail,
    selectedLgCatCd,
    selectedLgCatNm,
  ]);

  useEffect(() => {
    if (selectedLgCatCd) {
      dispatch(
        getOnSaleInfo({ lgCatCd: selectedLgCatCd, saleInfosIncFlag: "Y" })
      );
    }
  }, [selectedLgCatCd]);

  useEffect(() => {
    if (categories && saleInfos && Object.keys(saleInfos).length > 0) {
      const prdtId = saleInfos[0]?.saleProductInfos[0]?.prdtId;
      if (prdtId) {
        setFirstFocusableTarget("spotlightId-" + removeDotAndColon(prdtId));
        setIsReadyForInitialFocusTarget(true);
      }
    }
  }, [categories, saleInfos]);

  useEffect(() => {
    if (categories && isReadyForInitialFocusTarget && !isInitialFocusOccurred) {
      let targetId = "spotlightId-" + categories[0]?.lgCatCd;

      if (previousPanelIsDetail) {
        targetId = panelInfo?.targetId;
      }

      if (previousPanelIsHome) {
        // 홈에서 온세일 아이템을 선택한 경우 해당 카테고리의 nav 아이템에 포커스
        targetId = "spotlightId-" + panelInfo?.lgCatCd;
      }

      if (enteredThroughEventPopup) {
        targetId = "spotlightId-" + panelInfo?.lgCatCd;
      }

      initialFocusTimeoutJob.current.start(() => {
        const initialFocusTarget = document.querySelector(
          `[data-spotlight-id="${targetId}"]`
        );

        setSpotlightDisabled(false);

        if (initialFocusTarget) Spotlight.focus(initialFocusTarget);
        else {
          if (previousPanelIsHome) Spotlight.focus("sale-info-0");
        }

        setIsInitialFocusOccurred(true);
        dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
      });
    }
  }, [
    categories,
    enteredThroughEventPopup,
    isInitialFocusOccurred,
    isReadyForInitialFocusTarget,
    panelInfo?.lgCatCd,
    panelInfo?.targetId,
    previousPanelIsDetail,
    previousPanelIsHome,
  ]);

  useEffect(() => {
    if (categories && isInitialFocusOccurred && !previousPanelIsDetail) {
      let params = { logTpNo: LOG_TP_NO.CURATION.ON_SALE };

      if (!selectedLgCatCd) {
        if (enteredThroughGNB) {
          params = {
            ...params,
            expsOrd: getExpsOrdByLgCatCd(categories, categories[0]?.lgCatCd),
            lgCatCd: categories[0]?.lgCatCd,
            lgCatNm: categories[0]?.lgCatNm,
          };
        }

        if (enteredThroughEventPopup) {
          params = {
            ...params,
            expsOrd: getExpsOrdByLgCatCd(categories, panelInfo?.lgCatCd),
            lgCatCd: panelInfo?.lgCatCd,
            lgCatNm:
              categories //
                .find(({ lgCatCd }) => panelInfo?.lgCatCd === lgCatCd)
                ?.lgCatNm ?? "",
          };
        }

        if (previousPanelIsHome) {
          params = {
            ...params,
            expsOrd: getExpsOrdByLgCatCd(categories, panelInfo?.lgCatCd),
            lgCatCd: panelInfo?.lgCatCd,
            lgCatNm: panelInfo?.lgCatNm,
          };
        }
      } else {
        params = {
          ...params,
          expsOrd: getExpsOrdByLgCatCd(categories, selectedLgCatCd),
          lgCatCd: selectedLgCatCd,
          lgCatNm: selectedLgCatNm,
        };
      }

      dispatch(sendLogCuration(params));
    }
  }, [
    categories,
    enteredThroughEventPopup,
    enteredThroughGNB,
    isInitialFocusOccurred,
    panelInfo?.lgCatCd,
    panelInfo?.lgCatNm,
    previousPanelIsHome,
    previousPanelIsDetail,
    selectedLgCatCd,
    selectedLgCatNm,
  ]);

  useEffect(() => {
    return () => {
      const lastFocusedTarget = Spotlight.getCurrent();

      if (lastFocusedTarget) {
        const exprOrd = parseInt(
          lastFocusedTarget.getAttribute("data-exposure-order")
        );
        const lgCatCd = lastFocusedTarget.getAttribute("data-lg-category-code");
        const targetId = lastFocusedTarget.getAttribute("data-spotlight-id");

        dispatch(
          updatePanel({
            name: panel_names.ON_SALE_PANEL,
            panelInfo: {
              exprOrd,
              lgCatCd,
              targetId,
              focusedContainerId: focusedContainerIdRef.current,
              noResetFlag: true,
            },
          })
        );
      }

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

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

    timerRef.current = setTimeout(() => {
      Spotlight.focus(firstFocusableTarget);
      setIsTopButtonClicked(false);
    }, 200);
  }, [firstFocusableTarget]);

  const onFocusedContainerId = useCallback((containerId) => {
    focusedContainerIdRef.current = containerId;
  }, []);

  const onSaleNavClicked = useCallback((ev) => {
    setFirstFocusableTarget(ev);
    if (cbChangePageRef.current) {
      cbChangePageRef.current(0);
    }
  }, []);
  const handleShelfFocus = useCallback(
    (shelfOrder) => {
      // 현재 포커스된 shelf와 다른 shelf에 포커스될 때만 true 반환
      if (currentFocusedShelf !== shelfOrder) {
        setCurrentFocusedShelf(shelfOrder);
        return true; // dispatch 해야 함
      }
      return false; // dispatch 하지 않음
    },
    [currentFocusedShelf]
  );

  const handleCancel = useCallback(
    (e) => {
      if (panelInfo.nowShelf) {
        dispatch(
          updateHomeInfo({
            name: panel_names.HOME_PANEL,
            panelInfo: {
              nowShelf: panelInfo.nowShelf,
            },
          })
        );
      }
      dispatch(popPanel());
      e.stopPropagation();
    },
    [dispatch, panelInfo.nowShelf]
  );

  useEffect(() => {
    setTimeout(() => {
      dispatch(changeAppStatus({ cursorVisible: false }));
      Spotlight.setPointerMode(false);
    }, 100);
  }, []);

  return (
    <TPanel
      className={css.tPanel}
      spotlightId={spotlightId}
      handleCancel={handleCancel}
    >
      {categories && (
        <>
          <OnSaleNav
            categoryInfos={categories}
            panelInfoLgCatCd={panelInfo?.lgCatCd}
            previousPanelIsDetail={previousPanelIsDetail}
            selectedLgCatCd={selectedLgCatCd}
            setFirstFocusableTarget={onSaleNavClicked}
            setSelectedLgCatCd={setSelectedLgCatCd}
            setSelectedLgCatNm={setSelectedLgCatNm}
            spotlightDisabled={spotlightDisabled}
          />

          <TBody
            className={css.tBody}
            scrollable={false}
            spotlightDisabled={spotlightDisabled}
          >
            {saleInfos && (
              <TVerticalPagenator
                className={css.tVerticalPagenator}
                spotlightId={"onSale_verticalPagenator"}
                enableFocusAction={false}
                defaultContainerId={panelInfo?.focusedContainerId}
                onFocusedContainerId={onFocusedContainerId}
                cbChangePageRef={cbChangePageRef}
                topMargin={48}
              >
                <>
                  {saleInfos.map(
                    ({ saleNm, saleProductInfos, expsOrd }, contentsIndex) => (
                      <OnSaleContents
                        contentsIndex={contentsIndex}
                        isTopButtonClicked={isTopButtonClicked}
                        key={"sale-info-" + contentsIndex}
                        spotlightId={"sale-info-" + contentsIndex}
                        saleNm={saleNm}
                        shelfOrder={expsOrd}
                        saleProductInfos={saleProductInfos}
                        selectedLgCatCd={selectedLgCatCd}
                        selectedLgCatNm={selectedLgCatNm}
                        onShelfFocus={handleShelfFocus}
                      />
                    )
                  )}
                  {saleInfos.length > 1 && (
                    <TButton
                      onClick={handleTopButtonClick}
                      size={null}
                      type={TYPES.topButton}
                      ariaLabel="Move to Top"
                      data-wheel-point
                    />
                  )}
                </>
              </TVerticalPagenator>
            )}
          </TBody>
        </>
      )}
    </TPanel>
  );
}
