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

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

import { Job } from "@enact/core/util";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import {
  getContainerId,
  setContainerLastFocusedElement,
} from "@enact/spotlight/src/container";

import { pushPanel, updatePanel } from "../../../../actions/panelActions";
import TItemCard from "../../../../components/TItemCard/TItemCard";
import TVirtualGridList from "../../../../components/TVirtualGridList/TVirtualGridList";
import useScrollTo from "../../../../hooks/useScrollTo";
import {
  LOG_CONTEXT_NAME,
  LOG_MESSAGE_ID,
  panel_names,
} from "../../../../utils/Config";
import {
  getTranslate3dValueByDirection,
  scaleW,
} from "../../../../utils/helperMethods";
import css from "./OnSaleProductList.module.less";

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

export default function OnSaleProductList({
  contentsIndex,
  isTopButtonClicked,
  saleProductInfos,
  selectedLgCatCd,
  selectedLgCatNm,
  shelfOrder,
  shelfTitle,
  spotlightId,
}) {
  const { getScrollTo, scrollLeft } = useScrollTo();

  const dispatch = useDispatch();

  const panelInfo = useSelector((state) => state.panels.panels[0]?.panelInfo);

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

  useEffect(() => {
    const previousPanelIsHome = Object.keys(panelInfo)?.length === 3;

    if (previousPanelIsHome) {
      const container = document //
        .getElementById("on-sale-product-list-id-" + contentsIndex);

      const productIndex = saleProductInfos //
        .findIndex((product) => panelInfo?.prdtId === product?.prdtId);

      if (container && productIndex >= 0) {
        const xContainer = container?.firstChild?.firstChild?.firstChild;

        if (xContainer) {
          const containerWidth = 1800;
          const tabLayoutWidth = 120;
          const itemWidth = 324;
          const itemGap = 18;

          const displayOrder = productIndex + 1;

          const maxVisibleCount = //
            Math.floor(containerWidth / (itemWidth + itemGap));

          if (productIndex > maxVisibleCount) {
            const offsetFromContainerLeft =
              displayOrder * (itemWidth + itemGap) - tabLayoutWidth;
            const clippedWidth =
              containerWidth -
              (itemWidth + itemGap) * maxVisibleCount -
              itemGap;

            const x = scaleW(
              offsetFromContainerLeft -
                containerWidth +
                tabLayoutWidth +
                clippedWidth
            );

            setTimeout(() => {
              scrollLeft({ x });
            });
          }
        }
      }
    }
  }, [contentsIndex, panelInfo, saleProductInfos, scrollLeft]);

  useEffect(() => {
    if (!panelInfo?.exprOrd || panelInfo?.exprOrd !== contentsIndex + 1) {
      return;
    }

    const scrollLeftJobValue = scrollLeftJob.current;
    const { x } = panelInfo;

    scrollLeftJobValue.start(() => scrollLeft({ x }));

    return () => scrollLeftJobValue.stop();
  }, [contentsIndex, panelInfo, scrollLeft]);

  useEffect(() => {
    const containerId = "on-sale-product-list-id-" + contentsIndex;
    const container = document.getElementById(containerId);

    if (container) {
      const childrenId = getContainerId(container?.children[0].children[0]);

      if (childrenId) {
        setContainerLastFocusedElement(null, [containerId, childrenId]);
      }
    }

    scrollLeft();
  }, [contentsIndex, scrollLeft, selectedLgCatCd]);

  useEffect(() => {
    if (contentsIndex === 0 && isTopButtonClicked) {
      scrollLeft();
    }
  }, [contentsIndex, isTopButtonClicked, scrollLeft]);

  const handleClick = useCallback(
    (patnrId, prdtId) => (e) => {
      const tItemCard = e.currentTarget;
      const xContainer = tItemCard?.parentNode?.parentNode;

      if (xContainer) {
        const x = getTranslate3dValueByDirection(xContainer);

        dispatch(
          updatePanel({
            name: panel_names.ON_SALE_PANEL,
            panelInfo: { x },
          })
        );
      }

      dispatch(
        pushPanel({
          name: panel_names.DETAIL_PANEL,
          panelInfo: { patnrId, prdtId },
        })
      );
    },
    [dispatch]
  );

  const renderItem = useCallback(
    ({ index, ...rest }) => {
      const {
        imgUrl,
        lgCatCd,
        patnrId,
        prdtNm,
        prdtId,
        priceInfo,
        offerInfo,
        patncNm,
        brndNm,
      } = saleProductInfos[index];

      return (
        <TItemCard
          contextName={LOG_CONTEXT_NAME.ON_SALE}
          messageId={LOG_MESSAGE_ID.SHELF_CLICK}
          shelfLocation={shelfOrder}
          shelfTitle={shelfTitle}
          shelfId={spotlightId}
          category={selectedLgCatNm}
          patnerName={patncNm}
          brandName={brndNm}
          order={index + 1}
          className={css.tItemCard}
          data-lg-category-code={lgCatCd}
          data-exposure-order={contentsIndex + 1}
          imageAlt={prdtNm}
          imageSource={imgUrl}
          onClick={handleClick(patnrId, prdtId)}
          priceInfo={priceInfo}
          productId={prdtId}
          productName={prdtNm}
          offerInfo={offerInfo}
          label={index * 1 + 1 + " of " + saleProductInfos.length}
          lastLabel=" go to detail, button"
          {...rest}
        />
      );
    },
    [
      contentsIndex,
      handleClick,
      saleProductInfos,
      selectedLgCatNm,
      shelfOrder,
      shelfTitle,
      spotlightId,
    ]
  );

  return (
    <Container
      className={css.container}
      id={"on-sale-product-list-id-" + contentsIndex}
      spotlightId={"on-sale-product-list-id-" + contentsIndex}
    >
      {saleProductInfos && (
        <TVirtualGridList
          cbScrollTo={getScrollTo}
          className={css.tVirtualGridList}
          dataSize={saleProductInfos.length}
          direction="horizontal"
          itemHeight={438}
          itemWidth={324}
          spacing={18}
          renderItem={renderItem}
        />
      )}
    </Container>
  );
}
