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

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

import Alert from "@enact/sandstone/Alert";
import Spotlight from "@enact/spotlight";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import Spottable from "@enact/spotlight/Spottable";

import defaultImageItem from "../../../assets/images/img-thumb-empty-product@3x.png";
import { cancelFocusElement, focusElement } from "../../actions/commonActions";
import { SpotlightIds } from "../../utils/SpotlightIds";
import CustomImage from "../CustomImage/CustomImage";
import TButton from "../TButton/TButton";
import css from "../TPopUp/TPopUp.module.less";
import { $L } from "../../utils/helperMethods";

const Container = SpotlightContainerDecorator(
  { enterTo: "default-element" },
  Spottable("div")
);

const OptionContainer = SpotlightContainerDecorator(
  { enterTo: "last-focused" },
  Spottable("ul")
);

const ButtonContainer = SpotlightContainerDecorator("div");
const ButtonContainerNegative = SpotlightContainerDecorator(
  { defaultElement: `[data-spotlight-id="${"tPopupBtn2"}"]` },
  "div"
);
const SpottableComponent = Spottable("li");
const SpottableDiv = Spottable("div");

const KINDS = [
  "textPopup",
  "termsPopup",
  "introTermsPopup",
  "optionPopup",
  "eventBannerPopup",
  "supportPopup",
  "exitPopup",
  "couponPopup",
  "mobileSendPopup",
  "qrPopup",
  "checkoutTermsPopup",
  "scrollPopup",
  "watchPopup",
  "setPinCodePopup",
  "descriptionPopup",
  "errorPopup",
  "orderDetailPopup",
  "returnExchangePopup",
  "orderCancelPopup",
  "cancelConfirmPopup",
  "trackPackagePopup",
  "optionalAgreement",
  "normal",  
];

export default function TPopUp({
  kind,
  children,
  onExit,
  onClick,
  currentPage,
  onRightClick,
  onLeftClick,
  itemLength,
  onClose,
  hasButton,
  hasText,
  hasOnClose = false,
  hasIndicator,
  hasLogo,
  hasThumbnail,
  thumbnail,
  logo,
  className,
  button1Text,
  button2Text,
  open,
  title,
  text,
  type = "overlay",
  options,
  optionClick,
  selectedIndex,
  spotlightId,
  onSpotlightRight,
  ...rest
}) {
  const dispatch = useDispatch();
  const popupVisible = useSelector((state) => state.common.popup.popupVisible);
  const httpHeader = useSelector((state) => state.common.httpHeader);

  useEffect(() => {
    if (popupVisible) {
      if (spotlightId) {
        const timerId = setTimeout(() => {
          Spotlight.focus(spotlightId);
        }, 0);

        return () => {
          clearTimeout(timerId);
        };
      }
      const timerId = setTimeout(() => {
        Spotlight.focus(SpotlightIds.TPOPUP);
      }, 0);

      return () => {
        clearTimeout(timerId);
      };
    }
  }, [spotlightId, popupVisible]);

  useEffect(() => {
    if (KINDS.indexOf(kind) < 0) {
      console.error("TPopUp kind error");
    }
  }, [kind]);

  const ButtonContainerComp = useMemo(() => {
    return kind === "exitPopup" ? ButtonContainerNegative : ButtonContainer;
  }, [kind]);
  
  // optionalAgreement
  // 자동으로 Yes/No 버튼 텍스트 설정
  
  const finalButton1Text = useMemo(() => {
    if (kind === "optionalAgreement" && !button1Text) {
      return "Yes";
    }
    return button1Text;
  }, [kind, button1Text]);
  
  const finalButton2Text = useMemo(() => {
    if (kind === "optionalAgreement" && !button2Text) {
      return "No";
    }
    return button2Text;
  }, [kind, button2Text]);
  
  // optionalAgreement일 경우 항상 버튼 표시
  const shouldShowButtons = useMemo(() => {
    return hasButton || kind === "optionalAgreement";
  }, [hasButton, kind]);

  //-------------------------------------------------------

  const _onClick = useCallback(
    (e) => {
      if (onClick) {
        onClick(e);
      } else if (kind === "exitPopup") _onExit();
      else _onClose();
    },
    [onClick, kind, _onExit, _onClose]
  );

  const _optionClick = useCallback(
    (e, idx) => {
      if (optionClick) {
        optionClick(e, idx);
      }
    },
    [optionClick]
  );

  const _onExit = useCallback(
    (e) => {
      if (onExit) {
        onExit(e);
      }
    },
    [onExit]
  );

  const _onClose = useCallback(
    (e) => {
      if (onClose) {
        onClose(e);
      }
    },
    [onClose]
  );
  const selectedOptClick = useCallback(
    (index, optionStockQuantity) => (e) => {
      if (optionStockQuantity && optionStockQuantity <= 0) {
        return;
      }
      _optionClick(index);
    },
    [_optionClick]
  );

  const _onLeftClick = useCallback(
    (e) => {
      if (onLeftClick) {
        onLeftClick(e);
      }
    },
    [onLeftClick]
  );
  const _onRightClick = useCallback(
    (e) => {
      if (onRightClick) {
        onRightClick(e);
      }
    },
    [onRightClick]
  );

  const _onSpotlightRight = useCallback(
    (e) => {
      if (onSpotlightRight) {
        onSpotlightRight(e);
      }
    },
    [onSpotlightRight]
  );

  const ariaHidden = useMemo(() => {
    const deviceCountryCode = httpHeader?.["X-Device-Country"] || "";
    if (deviceCountryCode === "US") {
      return false;
    } else {
      return true;
    }
  }, [httpHeader]);
  return (
    <Alert
      open={open}
      onClose={_onClose}
      type={type}
      className={classNames(
        css.tPopUp,
        css[kind],
        title && css.title,
        text && css.text,
        hasButton && css.hasButton,
        kind === "optionalTermsConfirmPopup" && css.bottomPopup,
        className ? className : null
      )}
      aria-hidden={ariaHidden}
    >
      <Container className={css.info} spotlightId={SpotlightIds.TPOPUP}>
        {hasThumbnail && thumbnail && (
          <div className={css.thumbnail}>
            <CustomImage
              src={thumbnail}
              fallbackSrc={defaultImageItem}
              alt="thumbnail"
            />
          </div>
        )}
        {hasText && (
          <div className={css.textLayer}>
            {title && (
              <div className={css.title} aria-label={title + "heading 1"}>
                {title}
              </div>
            )}
            {hasLogo && logo !== null && (
              <span>
                <CustomImage
                  src={logo}
                  fallbackSrc={defaultImageItem}
                  alt="logo"
                />
              </span>
            )}
            {text && (
              <div className={css.text} aria-label={text}>
                {text}
              </div>
            )}
          </div>
        )}
        {options && (
          <OptionContainer
            className={classNames(
              css.optionLayer,
              options.length >= 5 ? css.optionScroll : null
            )}
          >
            {options.map((option, index) => {
              const { prodOptCval, optImgUrl, optPrc, optStkQty, optNm } =
                option;
              const optStock = Number(optStkQty);

              return (
                <SpottableComponent
                  {...rest}
                  className={classNames(
                    css.option,
                    optStkQty > 0 &&
                      index === selectedIndex &&
                      css.selectedOption,

                    index == selectedIndex && css.focused,
                    optStkQty <= 0 && css.optionSoldOut
                  )}
                  spotlightId={`selectedOptionBtn-${index}`}
                  onClick={selectedOptClick(index, optStkQty)}
                  key={`option: ${index}`}
                  aria-label={optNm ? optNm : prodOptCval}
                  spotlightDisabled={optStkQty && optStkQty <= 0}
                >
                  {optImgUrl && (
                    <CustomImage
                      src={optImgUrl}
                      className={css.img}
                      fallbackSrc={defaultImageItem}
                      alt="optionImg"
                    />
                  )}
                  <div className={css.optionItem}>
                    <span>{optNm ? optNm : prodOptCval}</span>
                    {optStkQty && optStkQty <= 0 && (
                      <span>{$L("SOLD OUT")}</span>
                    )}
                  </div>

                  {optPrc && optStock !== 0 && `($${optPrc})`}
                </SpottableComponent>
              );
            })}
          </OptionContainer>
        )}
        {children}
        {hasIndicator && (
          <>
            {currentPage !== 0 && (
              <SpottableDiv
                className={css.leftBtn}
                onClick={_onLeftClick}
                aria-label="Move to left"
                role="button"
              ></SpottableDiv>
            )}
            {currentPage !== itemLength - 1 && (
              <SpottableDiv
                className={css.rightBtn}
                onClick={_onRightClick}
                aria-label="Move to Right"
                role="button"
              ></SpottableDiv>
            )}
          </>
        )}
        {shouldShowButtons && (
          <ButtonContainerComp className={css.buttonContainer}>
            {finalButton1Text && (
              <TButton
                spotlightId="tPopupBtn1"
                onClick={_onClick}
                role="button"
                ariaLabel={finalButton1Text}
                onSpotlightRight={_onSpotlightRight}
              >
                {finalButton1Text}
              </TButton>
            )}
            {finalButton2Text && (
              <TButton
                spotlightId="tPopupBtn2"
                onClick={onClose}
                role="button"
                ariaLabel={finalButton2Text}
              >
                {finalButton2Text}
              </TButton>
            )}
          </ButtonContainerComp>
        )}
      </Container>
    </Alert>
  );
}
