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

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

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

import { sendLogCuration, sendLogGNB } from "../../actions/logActions";
import { updatePanel } from "../../actions/panelActions";
import CustomImage from "../../components/CustomImage/CustomImage";
import TPanel from "../../components/TPanel/TPanel";
import { LOG_TP_NO, panel_names } from "../../utils/Config";
import ImageOverlayContents from "./ImageOverlayContents/ImageOverlayContents";
import css from "./ImagePanel.module.less";
import ImageSideContents from "./ImageSideContents/ImageSideContents";

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

const findSelector = (selector, maxAttempts = 5, currentAttempts = 0) => {
  try {
    if (currentAttempts >= maxAttempts) {
      throw new Error("selector not found");
    }

    const initialSelector = document.querySelector(selector);

    if (initialSelector) {
      return initialSelector;
    } else {
      return findSelector(selector, maxAttempts, currentAttempts + 1);
    }
  } catch (error) {
    console.error(error.message);
  }
};

export default function ImagePanel({ panelInfo, spotlightId, ...rest }) {
  const dispatch = useDispatch();

  const brandShowroomInfo = useSelector(
    (state) => state.brand.brandShowroomData.data.brandShowroomInfo
  );

  const [isInitialFocusOccurred, setIsInitialFocusOccurred] = useState(false);
  const [otherRoomThemeInfos, setOtherRoomThemeInfos] = useState(null);
  const [overlayContentsVisible, setOverlayContentsVisible] = useState(true);
  const [selectedRoomThemeInfo, setSelectedRoomThemeInfo] = useState(null);
  const [selectedRoomThemeInfosLength, setSelectedRoomThemeInfosLength] =
    useState(null);
  const [selectedThemeExpsOrd, setSelectedThemeExpsOrd] = useState(null);
  const [sideContentsVisible, setSideContentsVisible] = useState(true);
  const [spotlightDisabled, setSpotlightDisabled] = useState(true);

  const initialFocusTimeoutJob = useRef(new Job((func) => func(), 100));
  const themeViewTimer = useRef(null);

  useEffect(() => {
    let sideCotnentsTimer;

    const handleAction = () => clearTimeout(sideCotnentsTimer);

    window.addEventListener("click", handleAction);
    window.addEventListener("keydown", handleAction);

    sideCotnentsTimer = setTimeout(() => setSideContentsVisible(false), 10000);

    return () => {
      window.removeEventListener("click", handleAction);
      window.removeEventListener("keydown", handleAction);

      clearTimeout(sideCotnentsTimer);
    };
  }, []);

  useEffect(() => {
    let overlayContentsTimer;

    const handleAction = () => clearTimeout(overlayContentsTimer);

    if (!sideContentsVisible) {
      window.addEventListener("click", handleAction);
      window.addEventListener("keydown", handleAction);

      overlayContentsTimer = setTimeout(
        () => setOverlayContentsVisible(false),
        3000
      );
    }

    return () => {
      window.removeEventListener("click", handleAction);
      window.removeEventListener("keydown", handleAction);

      clearTimeout(overlayContentsTimer);
    };
  }, [sideContentsVisible]);

  useEffect(() => {
    if (panelInfo && selectedRoomThemeInfo) {
      const params = {
        curationId: selectedRoomThemeInfo?.themeId,
        curationNm: selectedRoomThemeInfo?.themeNm,
        expsOrd: `${selectedRoomThemeInfo?.themeExpsOrd}`,
        logTpNo: LOG_TP_NO.CURATION.SHOWROOM,
        linkTpCd: panelInfo?.linkTpCd,
        patncNm: panelInfo?.patncNm,
        patnrId: panelInfo?.patnrId,
      };

      themeViewTimer.current = setTimeout(() => {
        dispatch(sendLogCuration(params));
      }, 3000);

      return () => clearTimeout(themeViewTimer.current);
    }
  }, [panelInfo, selectedRoomThemeInfo]);

  useEffect(() => {
    if (panelInfo) {
      setOtherRoomThemeInfos(
        brandShowroomInfo
          .find(({ roomId }) => roomId === panelInfo?.roomId)
          ?.roomThemeInfos //
          .filter(({ themeId }) => themeId !== panelInfo?.themeId)
      );

      setSelectedRoomThemeInfo(
        brandShowroomInfo
          .find(({ roomId }) => roomId === panelInfo?.roomId)
          ?.roomThemeInfos //
          .find(({ themeId }) => themeId === panelInfo?.themeId)
      );

      setSelectedRoomThemeInfosLength(
        brandShowroomInfo //
          .find(({ roomId }) => roomId === panelInfo?.roomId)?.roomThemeInfos
          ?.length
      );

      setSelectedThemeExpsOrd(panelInfo?.themeExpsOrd);
    }
  }, [brandShowroomInfo, panelInfo]);

  useEffect(() => {
    setOtherRoomThemeInfos(
      brandShowroomInfo
        .find(({ roomId }) => roomId === panelInfo?.roomId)
        ?.roomThemeInfos //
        .filter(({ themeExpsOrd }) => themeExpsOrd !== selectedThemeExpsOrd)
    );

    setSelectedRoomThemeInfo(
      brandShowroomInfo
        .find(({ roomId }) => roomId === panelInfo?.roomId)
        ?.roomThemeInfos //
        .find(({ themeExpsOrd }) => themeExpsOrd === selectedThemeExpsOrd)
    );
  }, [brandShowroomInfo, panelInfo?.roomId, selectedThemeExpsOrd]);

  useEffect(() => {
    if (!isInitialFocusOccurred) {
      let targetId;

      if (panelInfo?.lastFocusedTargetId) {
        targetId = panelInfo.lastFocusedTargetId;
      }
      //
      else if (panelInfo?.targetId) {
        targetId = panelInfo.targetId;
      }
      //
      else {
        targetId = "spotlightId-arrow";
      }

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

        setSpotlightDisabled(false);

        if (initialFocusTarget) {
          Spotlight.focus(initialFocusTarget);
        }

        setIsInitialFocusOccurred(true);
      });
    }
  }, [
    isInitialFocusOccurred,
    panelInfo?.lastFocusedTargetId,
    panelInfo?.targetId,
  ]);

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

      if (lastFocusedTarget) {
        const lastFocusedTargetId =
          lastFocusedTarget.getAttribute("data-spotlight-id");

        dispatch(
          updatePanel({
            name: panel_names.IMAGE_PANEL,
            panelInfo: {
              lastFocusedTargetId,
            },
          })
        );
      }
    };
  }, [dispatch]);

  const handleClick = useCallback(
    (e) => {
      if (sideContentsVisible) {
        if (e.target.id === "dark-gradient") {
          setSideContentsVisible(false);
        }
      } else {
        setOverlayContentsVisible((prev) => !prev);
      }
    },
    [sideContentsVisible]
  );

  const handleSeletedTab = useCallback((nowMenu) => {
    dispatch(sendLogGNB(nowMenu));
  }, []);

  return (
    <TPanel
      className={css.tPanel}
      isTabActivated={false}
      spotlightId={spotlightId}
      spotlightDisabled={spotlightDisabled}
    >
      {selectedRoomThemeInfo &&
        selectedRoomThemeInfosLength &&
        selectedThemeExpsOrd && (
          <Container
            className={classNames(
              css.container,
              sideContentsVisible && css.darkOverlay
            )}
            onClick={handleClick}
          >
            <figure>
              <CustomImage src={selectedRoomThemeInfo.themeImgUrl} alt="" />
            </figure>

            <ImageOverlayContents
              overlayContentsVisible={overlayContentsVisible}
              panelInfo={panelInfo}
              selectedRoomThemeInfosLength={selectedRoomThemeInfosLength}
              selectedThemeExpsOrd={selectedThemeExpsOrd}
              setOverlayContentsVisible={setOverlayContentsVisible}
              setSelectedThemeExpsOrd={setSelectedThemeExpsOrd}
              setSideContentsVisible={setSideContentsVisible}
              sideContentsVisible={sideContentsVisible}
              themeNm={selectedRoomThemeInfo.themeNm}
            />

            {sideContentsVisible && (
              <ImageSideContents
                otherRoomThemeInfos={otherRoomThemeInfos}
                handleSeletedTab={handleSeletedTab}
                selectedRoomThemeInfo={selectedRoomThemeInfo}
              />
            )}
          </Container>
        )}
    </TPanel>
  );
}
