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 SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";
import { getContainerId } from "@enact/spotlight/src/container";

import btnPlay from "../../../../assets/images/btn/btn-play-thumb-nor.png";
import defaultLogoImg from "../../../../assets/images/ic-tab-partners-default@3x.png";
import emptyHorImage from "../../../../assets/images/img-home-banner-empty-hor.png";
import emptyVerImage from "../../../../assets/images/img-home-banner-empty-ver.png";
import defaultImageItem from "../../../../assets/images/img-thumb-empty-product@3x.png";
import liveShow from "../../../../assets/images/tag-liveshow.png";
import { changeAppStatus } from "../../../actions/commonActions";
import { updateHomeInfo } from "../../../actions/homeActions";
import {
  sendLogTopContents,
  sendLogTotalRecommend,
} from "../../../actions/logActions";
import { pushPanel } from "../../../actions/panelActions";
import {
  finishVideoPreview,
  startVideoPlayer,
} from "../../../actions/playActions";
import CustomImage from "../../../components/CustomImage/CustomImage";
import usePriceInfo from "../../../hooks/usePriceInfo";
import {
  LOG_CONTEXT_NAME,
  LOG_MENU,
  LOG_MESSAGE_ID,
  LOG_TP_NO,
  panel_names,
} from "../../../utils/Config";
import { $L, formatGMTString } from "../../../utils/helperMethods";
import { TEMPLATE_CODE_CONF } from "../HomePanel";
import css from "./RandomUnit.module.less";

const SpottableComponent = Spottable("div");

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

export default function RandomUnit({
  bannerData,
  spotlightId,
  isHorizontal,
  handleShelfFocus,
  handleItemFocus,
  randomNumber,
}) {
  const dispatch = useDispatch();

  const bannerDetailInfos =
    bannerData && bannerData.bannerDetailInfos
      ? bannerData.bannerDetailInfos
      : [];

  const shptmTmplCd = useSelector(
    (state) => state.home?.bannerData?.shptmTmplCd
  );
  const nowMenu = useSelector((state) => state.common.menu.nowMenu);
  const entryMenu = useSelector((state) => state.common.menu.entryMenu);

  const homeCategory = useSelector(
    (state) => state.home.menuData?.data?.homeCategory
  );
  const countryCode = useSelector((state) => state.common.httpHeader.cntry_cd);

  // 정상적으로 로딩되면 빈객체로 넘어가고 , 에러가 나면 객체안에 타입이 담겨옵니다.
  const broadcast = useSelector((state) => state.common.broadcast);
  const { curationId, curationTitle } = useSelector((state) => state.home);
  const [randomData, setRandomData] = useState("");
  const [priceInfos, setpriceInfos] = useState("");
  const [isFocused, setIsFocused] = useState(false);
  const [videoError, setVideoError] = useState(false);
  const [liveIndicies, setLiveIndicies] = useState([]);

  const timerRef = useRef();
  const bannerDataRef = useRef(bannerData);
  const randomDataRef = useRef(
    bannerDetailInfos &&
      randomNumber !== undefined &&
      bannerDetailInfos.length > 0
      ? bannerDetailInfos[randomNumber]
      : null
  );

  const topContentsLogInfo = useMemo(() => {
    if (randomDataRef.current) {
      const currentRandomData = randomDataRef.current;

      let contId, contNm;

      switch (currentRandomData?.shptmBanrTpCd) {
        // case: "LIVE" or "VOD"
        case "DSP00301":
        case "DSP00302":
          contId = currentRandomData?.showId;
          contNm = currentRandomData?.showNm;
          break;

        // case: "Image Banner"
        case "DSP00303":
          contId = currentRandomData?.shptmLnkTpCd;
          contNm = currentRandomData?.shptmLnkTpNm;
          break;

        // case: "Today's Deals"
        default:
          contId = currentRandomData?.prdtId;
          contNm = currentRandomData?.prdtNm;
          break;
      }

      if (
        currentRandomData?.shptmLnkTpCd === "DSP00503" || // "Hot Picks"
        currentRandomData?.shptmLnkTpCd === "DSP00509" // "Theme"
      ) {
        contNm = contNm + " | " + currentRandomData?.lnkCurationId;
      }

      return {
        banrNo: `${currentRandomData?.banrDpOrd}`,
        banrTpNm: currentRandomData?.vtctpYn
          ? currentRandomData.vtctpYn === "Y"
            ? "Vertical"
            : "Horizontal"
          : "",
        contId,
        contNm,
        contTpNm: currentRandomData?.shptmBanrTpNm ?? "",
        dspyTpNm: bannerDataRef.current?.shptmDspyTpNm ?? "",
        expsOrd: bannerDataRef.current?.banrLctnNo ?? "",
        linkTpCd: "",
        patncNm: currentRandomData?.patncNm ?? "",
        patnrId: currentRandomData?.patnrId ?? "",
        tmplCd: shptmTmplCd,
      };
    }

    return {};
  }, [shptmTmplCd]);

  const sendBannerLog = useCallback(
    (bannerClick) => {
      const data = randomDataRef.current;

      const newParams =
        data.shptmBanrTpNm === "LIVE"
          ? {
              showId: data.showId,
              showTitle: data.showNm,
              displayType: "Fix",
              bannerType: "Horizontal",
            }
          : {
              contentId: data.showId,
              contentTitle: data.showNm,
              displayType: "Rolling",
              bannerType: "Vertical",
            };

      if (data && nowMenu === LOG_MENU.HOME_TOP) {
        const logParams = {
          contextName: LOG_CONTEXT_NAME.HOME,
          messageId: bannerClick
            ? LOG_MESSAGE_ID.BANNER_CLICK
            : LOG_MESSAGE_ID.BANNER,
          ...newParams,
          curationId,
          curationTitle,
          contentType: data.shptmBanrTpNm,
          productId: data.prdtId,
          productTitle: data.prdtNm,
          partner: data.patncNm,
          brand: data.brndNm, // <- 'brnad' 확인
          location: bannerData.banrLctnNo,
        };
        dispatch(sendLogTotalRecommend(logParams));
      }
    },
    [dispatch, nowMenu, curationId, curationTitle]
  );

  // 1. 비디오(live) 에러 감지
  // 2. 라이브 영상이 2개 이상이면, 그 다음 영상으로 전환
  // 3. 라이브 영상이 1개면 그 다음 영상으로 전환을 할 수 없으므로 에러 로고 화면을 보여준다.
  // 라이브 영상이 1개 라도 순간적인 네트워크 오류나, 일시적인 오류 일수 있으므로, 일정 시간을 주고, 비디오를 다시 호출 한다.

  useEffect(() => {
    if (
      bannerDetailInfos &&
      bannerDetailInfos.length > 0 &&
      randomNumber !== undefined
    ) {
      const indices = bannerDetailInfos
        .map((info, index) =>
          info && info.shptmBanrTpNm === "LIVE" ? index : null
        )
        .filter((index) => index !== null && index !== randomNumber);

      setLiveIndicies(indices);
    }
  }, [bannerDetailInfos, randomNumber]);

  // 비디오 에러일시, 클릭 이동
  const videoErrorClick = useCallback(() => {
    return dispatch(
      pushPanel({
        name: panel_names.FEATURED_BRANDS_PANEL,
        panelInfo: { from: "gnb", patnrId: randomData.patnrId },
      })
    );
  }, [randomData, dispatch]);

  // 포커스 인
  const onFocus = useCallback(() => {
    setIsFocused(true);

    if (handleItemFocus) {
      handleItemFocus();
    }
  }, [handleItemFocus]);

  const shelfFocus = useCallback(() => {
    if (handleShelfFocus) {
      handleShelfFocus();
    }
  }, [handleShelfFocus]);

  // 포커스 아웃
  const onBlur = useCallback(() => {
    setIsFocused(false);
    clearTimeout(timerRef.current);

    console.log("[RandomUnit] onBlur");
    dispatch(finishVideoPreview());
    console.log("[RandomUnit] finishVideoPreview");
  }, [isFocused]);

  // DSP00501 : Featured Brands
  // DSP00502 : Trending now
  // DSP00503 : HOT PICKS
  // DSP00504 : ON SALE
  // DSP00505 : CATEGORY
  // DSP00506 : Product Detail
  // DSP00507 : VOD
  // DSP00508 : Show Detail
  // DSP00509 : Theme

  const categoryData = useMemo(() => {
    if (randomData && randomData.shptmLnkTpCd === "DSP00505") {
      if (homeCategory && homeCategory.length > 0) {
        const foundCategory = homeCategory.find(
          (data) => data.lgCatCd === randomData.lgCatCd
        );
        if (foundCategory) {
          return {
            lgCatNm: foundCategory.lgCatNm,
            COUNT: foundCategory.COUNT,
          };
        }
        return;
      }
    }
  }, [homeCategory, randomData.shptmLnkTpCd]);

  // 이미지 배너 클릭
  const imageBannerClick = useCallback(() => {
    let linkInfo = {};
    const linkType = randomData.shptmLnkTpCd;

    switch (linkType) {
      case "DSP00501":
        linkInfo = {
          name: panel_names.FEATURED_BRANDS_PANEL,
          panelInfo: { from: "gnb", patnrId: randomData.patnrId },
        };
        break;

      case "DSP00502":
        linkInfo = {
          name: panel_names.TRENDING_NOW_PANEL,
          panelInfo: {},
        };
        break;

      case "DSP00503":
        linkInfo = {
          name: panel_names.HOT_PICKS_PANEL,
          panelInfo: {
            patnrId: randomData.patnrId,
            curationId: randomData.lnkCurationId,
          },
        };
        break;

      case "DSP00504":
        linkInfo = {
          name: panel_names.ON_SALE_PANEL,
          panelInfo: {
            lgCatCd: randomData.lgCatCd,
          },
        };
        break;

      case "DSP00505":
        if (Object.keys(categoryData).length > 0) {
          linkInfo = {
            name: panel_names.CATEGORY_PANEL,
            panelInfo: {
              lgCatCd: randomData.lgCatCd,
              lgCatNm: categoryData.lgCatNm,
              COUNT: categoryData.COUNT,
              currentSpot: null,
              dropDownTab: 0,
              tab: 0,
              focusedContainerId: null,
            },
          };
        }
        break;

      case "DSP00506":
        linkInfo = {
          name: panel_names.DETAIL_PANEL,
          panelInfo: {
            patnrId: randomData.patnrId,
            prdtId: randomData.prdtId,
            curationId: randomData.lnkCurationId,
          },
        };
        break;

      case "DSP00507":
        linkInfo = {
          patnrId: randomData.patnrId,
          showId: randomData.showId,
          shptmBanrTpNm: "VOD",
          lgCatCd: randomData.lgCatCd,
          modal: false,
        };
        break;

      case "DSP00508":
        linkInfo = {
          name: panel_names.DETAIL_PANEL,
          panelInfo: {
            patnrId: randomData.patnrId,
            curationId: randomData.lnkCurationId,
            prdtId: randomData.prdtId,
            type: "theme",
          },
        };
        break;

      case "DSP00509":
        linkInfo = {
          name: panel_names.THEME_CURATION_PANEL,
          panelInfo: {
            curationId: randomData.lnkCurationId,
          },
        };
        break;

      default:
        linkInfo = {
          name: panel_names.HOME_PANEL,
          panelInfo: {},
        };
        break;
    }

    let action = linkType === "DSP00507" ? startVideoPlayer : pushPanel;

    dispatch(action(linkInfo));
    sendBannerLog(true);
    dispatch(
      sendLogTopContents({
        ...topContentsLogInfo,
        inDt: formatGMTString(new Date()) ?? "",
        logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
      })
    );
  }, [
    categoryData,
    dispatch,
    randomData?.lgCatCd,
    randomData?.lnkCurationId,
    randomData?.patnrId,
    randomData?.prdtId,
    randomData?.showId,
    randomData?.shptmLnkTpCd,
    topContentsLogInfo,
    sendBannerLog,
  ]);

  // 투데이즈딜 클릭
  const todayDealClick = useCallback(() => {
    dispatch(
      pushPanel({
        name: panel_names.DETAIL_PANEL,
        panelInfo: {
          patnrId: randomData.patnrId,
          prdtId: randomData.prdtId,
        },
      })
    );

    sendBannerLog(true);

    dispatch(
      sendLogTopContents({
        ...topContentsLogInfo,
        inDt: formatGMTString(new Date()) ?? "",
        logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
      })
    );
  }, [
    dispatch,
    randomData?.patnrId,
    randomData?.prdtId,
    topContentsLogInfo,
    sendBannerLog,
  ]);

  // 비디오 클릭
  const videoClick = useCallback(() => {
    const lastFocusedTargetId = getContainerId(Spotlight.getCurrent());
    const currentSpot = Spotlight.getCurrent();
    if (lastFocusedTargetId) {
      dispatch(
        updateHomeInfo({
          name: panel_names.HOME_PANEL,
          panelInfo: {
            lastFocusedTargetId,
            focusedContainerId: TEMPLATE_CODE_CONF.TOP,
            currentSpot: currentSpot?.getAttribute("data-spotlight-id"),
          },
        })
      );
    }

    dispatch(
      startVideoPlayer({
        showUrl: randomData.showUrl,
        patnrId: randomData.patnrId,
        showId: randomData.showId,
        shptmBanrTpNm: randomData.showId ? randomData.shptmBanrTpNm : "MEDIA",
        lgCatCd: randomData.lgCatCd,
        chanId: randomData.brdcChnlId,
        modal: false,
        modalContainerId: spotlightId,
        modalClassName: css.videoModal,
      })
    );

    dispatch(
      sendLogTopContents({
        ...topContentsLogInfo,
        inDt: formatGMTString(new Date()) ?? "",
        logTpNo: LOG_TP_NO.TOP_CONTENTS.CLICK,
      })
    );

    sendBannerLog(true);
    onBlur();
  }, [
    randomData,
    spotlightId,
    topContentsLogInfo,
    nowMenu,
    randomDataRef,
    sendBannerLog,
    onBlur,
  ]);

  // 투데이즈 딜 가격 정보
  const { originalPrice, discountedPrice, discountRate, offerInfo } =
    usePriceInfo(priceInfos) || {};

  // 로그
  useEffect(() => {
    let _nowMenu = nowMenu;
    let _entryMenu = entryMenu;

    if (nowMenu === LOG_MENU.HOME_TOP) {
      const params = {
        ...topContentsLogInfo,
        entryMenu: _entryMenu,
        inDt: formatGMTString(new Date()) ?? "",
        logTpNo: LOG_TP_NO.TOP_CONTENTS.VIEW,
        nowMenu: _nowMenu,
      };

      return () => dispatch(sendLogTopContents(params));
    }
  }, [dispatch, entryMenu, nowMenu, topContentsLogInfo]);

  //통합로그
  useEffect(() => {
    sendBannerLog();
  }, [sendBannerLog]);

  useEffect(() => {
    if (
      bannerData &&
      bannerDetailInfos &&
      randomNumber !== undefined &&
      bannerDetailInfos.length > 0
    ) {
      setRandomData(bannerDetailInfos[randomNumber]);
    }
  }, [bannerData, bannerDetailInfos, randomNumber]);

  useEffect(() => {
    if (randomData && randomData.priceInfo !== null) {
      return setpriceInfos(randomData.priceInfo);
    }
  }, [randomData]);

  useEffect(() => {
    if (isFocused && !videoError) {
      timerRef.current = setTimeout(
        () =>
          dispatch(
            startVideoPlayer({
              showUrl: randomData.showUrl,
              patnrId: randomData.patnrId,
              showId: randomData.showId,
              shptmBanrTpNm: randomData.showId
                ? randomData.shptmBanrTpNm
                : "MEDIA",
              lgCatCd: randomData.lgCatCd,
              chanId: randomData.brdcChnlId,
              modal: true,
              modalContainerId: spotlightId,
              modalClassName: css.videoModal,
              isVerticalModal: !isHorizontal,
            })
          ),
        1000
      );
    }
    if (!isFocused) {
      setVideoError(false);
      // dispatch(finishVideoPreview());
    }
    return () => {
      clearTimeout(timerRef.current);
    };
  }, [isFocused]);

  useEffect(() => {
    if (isFocused && broadcast?.type === "videoError") {
      clearTimeout(timerRef.current);
      setVideoError(true);
      dispatch(finishVideoPreview());
      if (liveIndicies.length > 0) {
        const nextIndex = liveIndicies[0];

        setLiveIndicies((prev) => prev.slice(1));
        if (bannerDetailInfos && bannerDetailInfos[nextIndex]) {
          setRandomData(bannerDetailInfos[nextIndex]);
        }

        setTimeout(() => {
          setVideoError(false);
        }, 0);
      }
    }
  }, [broadcast]);

  // 데이터가 없으면 렌더링하지 않음
  if (!bannerData || !randomData || !bannerDetailInfos) {
    return null;
  }

  return (
    <>
      <Container
        className={classNames(
          css.rollingWrap,
          isHorizontal && css.isHorizontalWrap
        )}
        onFocus={shelfFocus}
      >
        {randomData?.shptmBanrTpNm == "Image Banner" ? (
          <SpottableComponent
            className={classNames(
              css.itemBox,
              isHorizontal && css.isHorizontal
            )}
            onClick={imageBannerClick}
            spotlightId={spotlightId}
            aria-label={
              randomData.prdtNm ? randomData.prdtNm : randomData.tmnlImgNm
            }
          >
            <div className={css.imgBanner}>
              <CustomImage
                delay={0}
                src={randomData.tmnlImgPath}
                animationSpeed="fast"
                ariaLabel={randomData.tmnImgNm}
              />
            </div>
          </SpottableComponent>
        ) : randomData?.shptmBanrTpNm == "LIVE" ||
          randomData?.shptmBanrTpNm == "VOD" ? (
          <SpottableComponent
            className={classNames(
              css.itemBox,
              isHorizontal && css.isHorizontal
            )}
            onClick={videoError === true ? videoErrorClick : videoClick}
            onFocus={onFocus}
            onBlur={onBlur}
            spotlightId={spotlightId}
            aria-label={
              randomData.shptmBanrTpNm == "LIVE"
                ? "LIVE " + randomData.showNm
                : randomData.showNm
            }
            alt={"LIVE"}
          >
            {randomData.shptmBanrTpNm == "LIVE" && videoError === false && (
              <p className={css.liveIcon}>
                <CustomImage
                  delay={0}
                  src={liveShow}
                  animationSpeed="fast"
                  ariaLabel="LIVE icon"
                />
              </p>
            )}

            {/* 비디오 에러 발생 */}
            {videoError === true && (
              <div className={css.errorContents}>
                <div>
                  {randomData.patncLogoPath && (
                    <img
                      className={css.errorlogo}
                      src={randomData.patncLogoPath}
                    />
                  )}
                  <p className={css.errorText}>
                    {$L("Click the screen to see more products!")}
                  </p>
                </div>
              </div>
            )}

            {/* 배너 메인 이미지 */}
            {videoError === false && (
              <div
                className={classNames(
                  css.itemBox,
                  isHorizontal && css.isHorizontal
                )}
              >
                {randomData.tmnlImgPath ? (
                  <CustomImage
                    delay={0}
                    src={randomData.tmnlImgPath}
                    ariaLabel={randomData.tmnImgNm}
                    animationSpeed="fast"
                  />
                ) : (
                  <CustomImage
                    delay={0}
                    src={
                      randomData.vtctpYn === "Y" ? emptyVerImage : emptyHorImage
                    }
                    animationSpeed="fast"
                    ariaLabel={randomData.tmnImgNm}
                  />
                )}
              </div>
            )}

            {/* 플레이 버튼 [>] */}
            {videoError === false && (
              <div className={css.btnPlay}>
                {randomData.tmnlImgPath == null ? "" : <img src={btnPlay} />}
              </div>
            )}

            {/* 배너 하단 로고 */}
            {videoError === false && (
              <p className={css.brandIcon}>
                {randomData.showId && (
                  <CustomImage
                    delay={0}
                    src={randomData.showId ? randomData.patncLogoPath : null}
                    fallbackSrc={defaultLogoImg}
                    animationSpeed="fast"
                    ariaLabel={randomData.brdcChnlId}
                  />
                )}
              </p>
            )}
          </SpottableComponent>
        ) : randomData?.shptmBanrTpNm == "Today's Deals" ? (
          <SpottableComponent
            className={classNames(
              css.itemBox,
              css.todaysDeals,
              countryCode === "RU" ? css.ru : "",
              countryCode === "DE" ? css.de : "",
              isHorizontal && css.isHorizontal
            )}
            onClick={todayDealClick}
            spotlightId={spotlightId}
            aria-label={
              randomData.prdtNm ? randomData.prdtNm : randomData.tmnlImgNm
            }
          >
            <div className={css.productInfo}>
              <div className={css.todaysDealTitle}>{$L("TODAY's DEALS")}</div>
              <div
                className={css.textBox}
                dangerouslySetInnerHTML={{
                  __html: `${randomData.prdtNm}`,
                }}
              />
              <div className={css.accBox}>
                {parseFloat(originalPrice?.replace("$", "")) === 0
                  ? randomData?.offerInfo
                  : discountRate
                    ? discountedPrice
                    : originalPrice}
                {discountRate && !isHorizontal && (
                  <span className={css.saleAccBox}>{originalPrice}</span>
                )}
              </div>
              {isHorizontal &&
                parseFloat(originalPrice?.replace("$", "")) !== 0 && (
                  <span className={css.saleAccBox}>{originalPrice}</span>
                )}
            </div>

            <div className={css.itemImgBox}>
              <CustomImage
                delay={0}
                src={randomData.tmnlImgPath}
                animationSpeed="fast"
                fallbackSrc={defaultImageItem}
                ariaLabel={randomData.tmnlImgNm}
              />
            </div>
          </SpottableComponent>
        ) : null}
      </Container>
    </>
  );
}
