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 {
  getCheckoutTotalAmt,
  getMyInfoCheckoutInfo,
  resetCheckoutData,
} from "../../actions/checkoutActions";
import {
  changeAppStatus,
  setHidePopup,
  setShowPopup,
} from "../../actions/commonActions";
import { getShoptimeTerms } from "../../actions/empActions";
import { popPanel } from "../../actions/panelActions";
import TBody from "../../components/TBody/TBody";
import TButton from "../../components/TButton/TButton";
import TButtonScroller from "../../components/TButtonScroller/TButtonScroller";
import TButtonTab from "../../components/TButtonTab/TButtonTab";
import TFullPopup from "../../components/TFullPopup/TFullPopup";
import THeader from "../../components/THeader/THeader";
import TPanel from "../../components/TPanel/TPanel";
import TPopUp from "../../components/TPopUp/TPopUp";
import TQRCode from "../../components/TQRCode/TQRCode";
import useLogService from "../../hooks/useLogService";
import useScrollTo from "../../hooks/useScrollTo";
import * as Config from "../../utils/Config";
import { $L, scaleH, scaleW } from "../../utils/helperMethods";
import { SpotlightIds } from "../../utils/SpotlightIds";
import css from "./CheckOutPanel.module.less";
import PinCodeInput from "./components/PinCodeInput";
import FixedSideBar from "./container/FixedSideBar";
import InformationContainer from "./container/InformationContainer";
import OrderItemsSideBar from "./container/OrderItemsSideBar";
import SummaryContainer from "./container/SummaryCotainer";

export default function CheckOutPanel() {
  const { sendLogGNB } = useLogService();
  const dispatch = useDispatch();
  const panels = useSelector((state) => state.panels.panels);
  const { userNumber } = useSelector(
    (state) => state.common.appStatus.loginUserData
  );
  const checkoutPanelInfo = panels.find(
    (panel) => panel.name === "checkoutpanel"
  )?.panelInfo;

  const productData = useSelector(
    (state) => state.checkout?.checkoutData.productList
  );
  const infoForCheckoutData = useSelector(
    (state) => state.checkout?.infoForCheckoutData
  );
  const selectedCoupons = useSelector(
    (state) => state.checkout.selectedCoupons
  );
  const empTermsData = useSelector((state) => state.emp.empTermsData.terms);
  const { popupVisible, activePopup } = useSelector(
    (state) => state.common.popup
  );
  const popup = useSelector((state) => state.common.popup);
  const { currSign, currSignLoc } = productData?.[0] || {};

  const [orderSideBarOpen, setOrderSideBarOpen] = useState(false);
  const [offerSideBarOpen, setOfferSideBarOpen] = useState(false);
  const [placeOrderPopup, setPlaceOrderPopup] = useState(false);
  const [currentTerms, setCurrentTerms] = useState(null);
  const [tabList, setTabList] = useState([]);
  const [selectedTabIndex, setSelectedTabIndex] = useState(0);
  const [resetScroll, setResetScroll] = useState(false);

  const isMounted = useRef(true);

  const { getScrollTo: getScrollToBody, scrollTop: scrollTopBody } =
    useScrollTo();

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

  useEffect(() => {
    let nowMenu;

    if (!placeOrderPopup || popupVisible) {
      nowMenu = Config.LOG_MENU.CHECKOUT;
    } else if (placeOrderPopup) {
      nowMenu = Config.LOG_MENU.CHECKOUT_PIN_CODE;
    }

    sendLogGNB(nowMenu);
  }, [placeOrderPopup, popupVisible, sendLogGNB]);

  useEffect(() => {
    isMounted.current = true;

    return () => {
      isMounted.current = false;
    };
  }, []);

  useEffect(() => {
    dispatch(getShoptimeTerms());
  }, [dispatch]);

  function totalAmtValidate(response) {
    if (response) {
      if (response.retCode !== 0) {
        if (response.retMsg) {
          dispatch(
            setShowPopup(Config.ACTIVE_POPUP.errorPopup, {
              text: response.retMsg,
            })
          );
        }
      }
    }
  }

  useEffect(() => {
    if (infoForCheckoutData && productData) {
      const orderProductCoupontUse = Object.keys(selectedCoupons).map(
        (productId) => {
          const { cpnCdSeq, cpnSno, prdtId } = selectedCoupons[productId];
          const product = productData.find((prod) => prod.prdtId === prdtId);

          return {
            cpnCdSeq,
            cpnSno,
            prdtId,
            prodSno: product?.prodSno,
            patnrId: product?.patnrId,
          };
        }
      );

      if (
        infoForCheckoutData &&
        infoForCheckoutData.dlvrAddrSno &&
        infoForCheckoutData.bilAddrSno
      ) {
        dispatch(
          getCheckoutTotalAmt(
            {
              mbrNo: userNumber,
              dirPurcSelYn: "Y",
              bilAddrSno: infoForCheckoutData.bilAddrSno,
              dlvrAddrSno: infoForCheckoutData.dlvrAddrSno,
              orderProductCoupontUse,
            },
            totalAmtValidate
          )
        );
      }
    }
  }, [dispatch, infoForCheckoutData, productData, userNumber, selectedCoupons]);

  useEffect(() => {
    const newTabList = [];

    if (empTermsData) {
      empTermsData.forEach((term) => {
        newTabList.push(term.termsTypeName);
      });

      setTabList(newTabList);
    }
  }, [empTermsData]);

  useEffect(() => {
    return () => {
      dispatch(resetCheckoutData());
    };
  }, [dispatch]);

  useEffect(() => {
    const spotJobValue = spotJob.current;

    spotJobValue.start(() => {
      if (!activePopup) {
        Spotlight.focus("spotlightId_placeOrderBtn");
      } else if (activePopup === Config.ACTIVE_POPUP.errorPopup) {
        Spotlight.focus(SpotlightIds.TPOPUP);
      }
    });

    return () => {
      spotJobValue.stop();
    };
  }, [activePopup]);

  const onBackClick = useCallback(() => {
    dispatch(popPanel());
  }, [dispatch]);

  const toggleOrderSideBar = useCallback(() => {
    setOrderSideBarOpen((prev) => !prev);
  }, []);

  const toggleOfferSideBar = useCallback(() => {
    setOfferSideBarOpen((prev) => !prev);
  }, []);

  const onClosePopup = useCallback(() => {
    setPlaceOrderPopup(false);
  }, []);

  const onCloseTermsPopup = useCallback(() => {
    dispatch(setHidePopup());
  }, [dispatch]);

  const handlePopPanel = useCallback(() => {
    dispatch(setHidePopup());
    dispatch(popPanel());
  }, [dispatch]);

  const handleTermsClick = useCallback(
    (termsID) => {
      if (empTermsData) {
        const selectedTerms = empTermsData.find(
          (term) => term.termsID === termsID
        );

        setCurrentTerms(selectedTerms);
        dispatch(setShowPopup(Config.ACTIVE_POPUP.termsPopup));

        const selectedIndex = empTermsData.findIndex(
          (term) => term.termsID === termsID
        );

        setSelectedTabIndex(selectedIndex);
        setResetScroll(true);
      }
    },
    [empTermsData, dispatch]
  );

  const handleTabClick = useCallback(({ index }) => {
    setSelectedTabIndex(index);
    setResetScroll(true);
  }, []);

  useEffect(() => {
    if (empTermsData && empTermsData[selectedTabIndex]) {
      setCurrentTerms(empTermsData[selectedTabIndex]);
      setResetScroll(true);
    }
  }, [selectedTabIndex, empTermsData]);

  useEffect(() => {
    if (resetScroll) {
      setResetScroll(false);
    }
  }, [resetScroll]);

  useEffect(() => {
    Spotlight.focus();
  }, [popupVisible, orderSideBarOpen, offerSideBarOpen]);

  return (
    <>
      <TPanel
        isTabActivated={false}
        spotlightDisabled={orderSideBarOpen || offerSideBarOpen}
      >
        <TBody className={css.tbody} cbScrollTo={getScrollToBody}>
          <THeader
            className={css.theader}
            title="CHECKOUT"
            onBackButton
            onClick={onBackClick}
          />
          <div className={css.Wrap}>
            <SummaryContainer
              setPlaceOrderPopup={setPlaceOrderPopup}
              empTermsData={empTermsData}
              handleTermsClick={handleTermsClick}
              currSign={currSign}
              currSignLoc={currSignLoc}
            />
            <InformationContainer
              toggleOrderSideBar={toggleOrderSideBar}
              toggleOfferSideBar={toggleOfferSideBar}
              scrollTopBody={scrollTopBody}
            />
          </div>
        </TBody>
      </TPanel>

      {orderSideBarOpen && (
        <OrderItemsSideBar closeSideBar={toggleOrderSideBar} />
      )}
      {offerSideBarOpen && (
        <FixedSideBar
          closeSideBar={toggleOfferSideBar}
          offerSideBarOpen={offerSideBarOpen}
        />
      )}

      {activePopup === Config.ACTIVE_POPUP.termsPopup && (
        <TPopUp
          kind="introTermsPopup"
          open={popupVisible}
          onClose={onCloseTermsPopup}
          hasButton
          button1Text={$L("OK")}
        >
          {currentTerms && (
            <div className={css.termsConts}>
              <TButtonTab
                className={css.tab}
                selectedIndex={selectedTabIndex}
                onItemClick={handleTabClick}
                contents={tabList}
                role="button"
              />
              <TButtonScroller
                boxHeight={scaleH(300)}
                width={scaleW(980)}
                className={css.termsDescription}
                resetScrollPosition={resetScroll}
                forcedFocus={false}
              >
                <div
                  className={css.termsDesc}
                  dangerouslySetInnerHTML={{
                    __html: currentTerms && currentTerms.termContent,
                  }}
                ></div>
              </TButtonScroller>
            </div>
          )}
        </TPopUp>
      )}

      {activePopup === Config.ACTIVE_POPUP.errorPopup && (
        <TPopUp
          kind="errorPopup"
          hasText
          open={popupVisible}
          text={popup.text ? popup.text : "unknown error"}
          hasButton
          button1Text={$L("CLOSE")}
          onClick={handlePopPanel}
        />
      )}

      <TFullPopup
        open={placeOrderPopup}
        className={css.pinCodePopup}
        onClose={onClosePopup}
        noAnimation={true}
      >
        <PinCodeInput setPlaceOrderPopup={setPlaceOrderPopup} />
      </TFullPopup>
    </>
  );
}
