import React, { useCallback, useEffect, useMemo, 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 playImg from "../../../../../assets/images/btn/btn-play-thumb-nor.png";
import indicatorDefaultImage from "../../../../../assets/images/img-thumb-empty-144@3x.png";
import defaultImage from "../../../../../assets/images/img-thumb-empty-560.png";
import { updatePanel } from "../../../../actions/panelActions";
import {
  finishVideoPreview,
  startVideoPlayer,
} from "../../../../actions/playActions";
import CustomImage from "../../../../components/CustomImage/CustomImage";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import usePriceInfo from "../../../../hooks/usePriceInfo";
import useScrollTo from "../../../../hooks/useScrollTo";
import { panel_names } from "../../../../utils/Config";
import { $L, scaleW } from "../../../../utils/helperMethods";
import css from "./Indicator.module.less";

const Container = SpotlightContainerDecorator(
  { enterTo: "default-element", preserveld: true },
  "div"
);
const SpottableComponent = Spottable("div");
const IMAGE_WIDTH = scaleW(152);
function Indicator({
  selectedIndex,
  setSelectedIndex,
  productInfo,
  soldoutFlag,
  launchedFromPlayer,
  isPlayerFinished,
  isOnTop,
}) {
  const dispatch = useDispatch();
  const { cursorVisible } = useSelector((state) => state.common.appStatus);
  const promotionPrcie = usePriceInfo(productInfo?.priceInfo);
  const isLoading = useSelector(
    (state) => state.common.appStatus?.showLoadingPanel?.show
  );
  const panels = useSelector((state) => state.panels.panels);
  const [autoPlaying, setAutoPlaying] = useState(
    !launchedFromPlayer && productInfo?.prdtMediaUrl
  );
  const [isLaunchedFromPlayer, setIsLaunchedFromPlayer] =
    useState(launchedFromPlayer);

  const [focused, setFocused] = useState(false);
  const { getScrollTo, scrollTop } = useScrollTo();
  const topPanel = panels[panels.length - 1];
  let imagePosition = IMAGE_WIDTH * selectedIndex - IMAGE_WIDTH;

  const canPlayVideo = useMemo(() => {
    return productInfo.prdtMediaUrl && selectedIndex === 0;
  }, [productInfo, selectedIndex]);

  useEffect(() => {
    if (
      topPanel &&
      topPanel.name === panel_names.PLAYER_PANEL &&
      !productInfo?.prdtMediaUrl
    ) {
      dispatch(finishVideoPreview());
    }
  }, [productInfo]);

  useEffect(() => {
    if (!isLaunchedFromPlayer && launchedFromPlayer && isPlayerFinished) {
      setIsLaunchedFromPlayer(true);
    }
  }, [isPlayerFinished]);

  useEffect(() => {
    if (
      topPanel &&
      topPanel.name === panel_names.PLAYER_PANEL &&
      topPanel.panelInfo.modal === false
    ) {
      return; //prevent
    }

    if (!isLaunchedFromPlayer && autoPlaying && productInfo?.prdtMediaUrl) {
      //auto play.
      dispatch(
        startVideoPlayer({
          showUrl: productInfo?.prdtMediaUrl,
          showNm: productInfo?.prdtNm,
          patnrNm: productInfo?.patncNm,
          patnrId: productInfo?.patnrId,
          patncLogoPath: productInfo?.patncLogoPath,
          orderPhnNo: productInfo?.orderPhnNo,
          disclaimer: productInfo?.disclaimer,
          subtitle: productInfo?.prdtMediaSubtitlUrl,
          lgCatCd: productInfo?.catCd,
          lgCatNm: productInfo?.catNm,
          prdtId: productInfo?.prdtId,
          prdtNm: productInfo?.prdtNm,
          patncNm: productInfo?.patncNm,
          thumbnailUrl: productInfo?.thumbnailUrl960,
          modal: true,
          shptmBanrTpNm: "MEDIA",
          modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
          modalClassName: modalClassNameChange(),
          spotlightDisable: true,
        })
      );
    }
  }, [
    dispatch,
    productInfo,
    autoPlaying,
    focused,
    isLaunchedFromPlayer,
    selectedIndex,
  ]);

  const modalClassNameChange = useCallback(() => {
    if (selectedIndex === 0) {
      if (focused) {
        return css.videoModal;
      }
      return "";
    } else {
      return css.videoModalHide;
    }
  }, [selectedIndex, focused]);

  const videoContainerOnFocus = useCallback(() => {
    if (canPlayVideo) {
      setFocused(true);
    }
  }, [canPlayVideo]);

  const videoContainerOnBlur = useCallback(() => {
    if (canPlayVideo) {
      setFocused(false);
    }
  }, [canPlayVideo]);

  const handleUpClick = useCallback(() => {
    if (selectedIndex === 0) {
      return;
    }
    setSelectedIndex((prev) => prev - 1);
    if (listImages.length - 1 !== selectedIndex) {
      scrollTop({ y: imagePosition - IMAGE_WIDTH, animate: true });
    }
  }, [selectedIndex, listImages]);

  const handleDownClick = useCallback(() => {
    if (listImages.length - 1 === selectedIndex) {
      return;
    }
    setSelectedIndex((prev) => prev + 1);
    if (selectedIndex > 1) {
      scrollTop({
        y: imagePosition,
        animate: true,
      });
    }
  }, [selectedIndex, listImages]);

  useEffect(() => {
    if (selectedIndex === 0) {
      scrollTop({
        y: 0,
      });
    }
  }, [selectedIndex, isLoading]);

  const handleVideoOnClick = useCallback(() => {
    if (canPlayVideo) {
      dispatch(
        startVideoPlayer({
          qrCurrentItem: productInfo,
          showUrl: productInfo?.prdtMediaUrl,
          showNm: productInfo?.prdtNm,
          patnrNm: productInfo?.patncNm,
          patncLogoPath: productInfo?.patncLogoPath,
          orderPhnNo: productInfo?.orderPhnNo,
          disclaimer: productInfo?.disclaimer,
          subtitle: productInfo?.prdtMediaSubtitlUrl,
          lgCatCd: productInfo?.catCd,
          patnrId: productInfo?.patnrId,
          lgCatNm: productInfo?.catNm,
          prdtId: productInfo?.prdtId,
          patncNm: productInfo?.patncNm,
          prdtNm: productInfo?.prdtNm,
          thumbnailUrl: productInfo?.thumbnailUrl960,
          shptmBanrTpNm: "MEDIA",
          modal: isLaunchedFromPlayer ? true : false,
          modalContainerId: "indicator_videoContainer", //to calc width, height, left, top
          modalClassName: css.videoModal,
          spotlightDisable: true,
        })
      );
    }

    if (isLaunchedFromPlayer) {
      setIsLaunchedFromPlayer(false);
    }

    if (isPlayerFinished) {
      dispatch(
        updatePanel({
          name: panel_names.DETAIL_PANEL,
          panelInfo: {
            isPlayerFinished: false,
          },
        })
      );
    }
    if (!autoPlaying && canPlayVideo) {
      setAutoPlaying(true);
    }
  }, [
    autoPlaying,
    isLaunchedFromPlayer,
    isPlayerFinished,
    canPlayVideo,
    productInfo,
  ]);

  const onSpotlightRight = useCallback(
    (ev) => {
      Spotlight.focus(`indicator-image-${selectedIndex}`);
      ev.stopPropagation();
      ev.preventDefault();
    },
    [selectedIndex]
  );

  const onSpotlightLeft = useCallback(
    (ev) => {
      if (isOnTop) Spotlight.focus("spotlightId_backBtn");
      ev.stopPropagation();
      ev.preventDefault();
    },
    [isOnTop]
  );

  const listImages = useMemo(() => {
    const images = [...productInfo.imgUrls600];
    if (productInfo?.prdtMediaUrl !== null) {
      images.splice(
        0,
        0,
        productInfo.thumbnailUrl960 !== null
          ? productInfo.thumbnailUrl960
          : indicatorDefaultImage
      );
    }
    return images;
  }, [productInfo]);

  const selectedImage = useMemo(() => {
    return listImages[selectedIndex];
  }, [listImages, selectedIndex]);

  const renderItem = useCallback(
    ({ index, ...rest }) => {
      const handleItemClick = () => {
        setSelectedIndex(index);
      };

      return (
        <>
          <SpottableComponent
            className={classNames(
              css.image,
              selectedIndex === index ? css.selected : undefined,
              soldoutFlag ? css.selected : undefined
            )}
            onClick={handleItemClick}
            spotlightId={`indicator-image-${index}`}
            aria-label={
              index === 0
                ? "Selected, " + productInfo.prdtNm + " " + "1"
                : productInfo.prdtNm + " " + `${index + 1}`
            }
            {...rest}
          >
            <CustomImage
              src={listImages[index]}
              alt=""
              fallbackSrc={indicatorDefaultImage}
              className={classNames(css.smallImage)}
            />

            <span
              className={
                selectedIndex === index &&
                (listImages.length !== 1 || !soldoutFlag)
                  ? css.checkIcon
                  : undefined
              }
            />
            {((listImages.length === 1 && soldoutFlag) ||
              (selectedIndex !== index && soldoutFlag)) && (
              <h3 className={css.soldoutLabel}>{$L("SOLD OUT")}</h3>
            )}
          </SpottableComponent>
        </>
      );
    },
    [listImages, selectedIndex, soldoutFlag]
  );

  const savePrice = parseFloat(
    promotionPrcie?.discountAmount.replace(/[^0-9.-]+/g, "") || 0
  );

  const renderThumbnail = useCallback(() => {
    return (
      <div className={css.thumbnailContainer}>
        <SpottableComponent
          spotlightId="indicator_videoContainer"
          disabled={!canPlayVideo}
          spotlightDisabled={!canPlayVideo}
          className={classNames(css.thumbnail)}
          onSpotlightRight={onSpotlightRight}
          onSpotlightLeft={onSpotlightLeft}
          onClick={handleVideoOnClick}
          onFocus={videoContainerOnFocus}
          onBlur={videoContainerOnBlur}
          aria-label={productInfo?.prdtNm}
        >
          <CustomImage
            className={css.image}
            src={selectedImage}
            fallbackSrc={autoPlaying && canPlayVideo ? "" : defaultImage}
            alt=""
          />

          {isLaunchedFromPlayer && canPlayVideo && (
            <h3>
              <img src={playImg} alt="Play" />
            </h3>
          )}

          {promotionPrcie?.promotionCode &&
            (!productInfo.prdtMediaUrl || autoPlaying) && (
              <div className={css.promotionImage}>
                <p className={css.badgeTitle}>{$L("Launch Event")}</p>
                <p className={css.badgeTitle}>{$L("Promo Code")}</p>
                <p className={css.badgeDate}>{promotionPrcie?.promotionDate}</p>
                {savePrice && (
                  <h5>
                    {`$${savePrice}`}
                    <br /> <span>{$L("OFF")}</span>
                  </h5>
                )}
              </div>
            )}
        </SpottableComponent>
      </div>
    );
  }, [
    productInfo,
    selectedIndex,
    selectedImage,
    autoPlaying,
    canPlayVideo,
    isLaunchedFromPlayer,
  ]);

  return (
    <Container className={css.indicatorContainer}>
      {renderThumbnail()}
      <div>
        <SpottableComponent
          onClick={handleUpClick}
          spotlightDisabled={!cursorVisible}
          className={classNames(
            css.upButton,
            selectedIndex === 0 && css.disable
          )}
          aria-label="Move to up"
        />
        <div className={css.tVirtualGridListContainer}>
          {productInfo && (
            <TVirtualGridList
              cbScrollTo={getScrollTo}
              className={css.tVirtualGridList}
              dataSize={listImages.length > 0 ? listImages.length : 1}
              itemWidth={144}
              itemHeight={144}
              spacing={8}
              renderItem={renderItem}
              spotlightId="indicator-GridListContainer"
            />
          )}
        </div>
        <SpottableComponent
          onClick={handleDownClick}
          spotlightDisabled={!cursorVisible}
          className={classNames(
            css.downButton,
            listImages.length - 1 === selectedIndex && css.disable
          )}
          aria-label="Move to down"
        />
      </div>
    </Container>
  );
}
const propsAreEqual = (prev, next) => {
  const keys = Object.keys(prev);
  const nextKeys = Object.keys(next);
  if (keys.length !== nextKeys.length) {
    return false;
  }
  for (let i = 0; i < keys.length; i++) {
    if (prev[keys[i]] !== next[keys[i]]) {
      if (JSON.stringify(prev[keys[i]]) === JSON.stringify(next[keys[i]])) {
        continue;
      }
      return false;
    }
  }
  return true;
};
export default React.memo(Indicator, propsAreEqual);
