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

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

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

import { setHidePopup, setShowPopup } from "../../../actions/commonActions";
import { getMyInfoCardPincodeCheck } from "../../../actions/pinCodeActions";
import TButton from "../../../components/TButton/TButton";
import TPopUp from "../../../components/TPopUp/TPopUp";
import TQRCode from "../../../components/TQRCode/TQRCode";
import * as Config from "../../../utils/Config";
import { $L } from "../../../utils/helperMethods";
import { SpotlightIds } from "../../../utils/SpotlightIds";
import css from "./PinCodeInput.module.less";

const PinCodeContainer = SpotlightContainerDecorator("div");

const SpottableButton = Spottable("div");

export default function PinCodeInput({ setPlaceOrderPopup }) {
  const dispatch = useDispatch();

  const { activePopup, popupVisible } = useSelector(
    (state) => state.common.popup
  );
  const pinCodeDatas = useSelector((state) => state.pinCode.pinCodeData);
  const userNumber = useSelector(
    (state) => state.common.appStatus.loginUserData.userNumber
  );

  const [pin, setPin] = useState(["", "", "", ""]);
  const [errorMsg, setErrorMsg] = useState("");
  const [okClicked, setOkClicked] = useState(false);

  useEffect(() => {
    if (pinCodeDatas && pinCodeDatas.retCode !== 0 && okClicked) {
      if (pinCodeDatas.data.pwdErrorCnt >= 3) {
        dispatch(setShowPopup(Config.ACTIVE_POPUP.setPinCodePopup));
      } else {
        setErrorMsg($L("Your entries did not match. Please try again."));
      }
    }
  }, [pinCodeDatas, dispatch, okClicked]);

  useEffect(() => {
    setOkClicked(false);
  }, []);

  useEffect(() => {
    if (popupVisible && activePopup) {
      setTimeout(() => {
        Spotlight.focus("tPopupBtn1");
      }, 0);
    }
  }, [popupVisible, activePopup]);

  const handleDigitClick = useCallback(
    (digit) => {
      const newPin = [...pin];
      const nextIndex = pin.findIndex((p) => p === "");

      if (nextIndex !== -1) {
        newPin[nextIndex] = digit;
        setPin(newPin);
      }
    },
    [pin]
  );

  const handleBackspace = useCallback(() => {
    const newPin = [...pin];
    const lastIndex = newPin.findIndex((p) => p === "");
    const index = lastIndex === -1 ? 3 : lastIndex - 1;

    if (index >= 0) {
      newPin[index] = "";
      setPin(newPin);
    }
  }, [pin]);

  const onClickCancel = useCallback(() => {
    setPin(["", "", "", ""]);
    setPlaceOrderPopup(false);
  }, [setPlaceOrderPopup]);

  const onClickConfirm = useCallback(() => {
    if (pin.includes("")) {
      setErrorMsg($L("Please enter a PIN CODE."));
      return;
    }

    setOkClicked(true);

    const pinString = pin.join("");
    const encryptedPin = CryptoJS.SHA256(pinString).toString();

    dispatch(
      getMyInfoCardPincodeCheck({
        mbrNo: userNumber,
        pinCd: encryptedPin,
      })
    );
  }, [pin, userNumber, dispatch]);

  const handleClickSetPinCode = useCallback(() => {
    dispatch(setShowPopup(Config.ACTIVE_POPUP.qrPopup));
  }, [dispatch]);

  const handleCancelPopup = useCallback(() => {
    dispatch(setHidePopup());
    Spotlight.focus(SpotlightIds.PINCODE_CONTAINER);
  }, [dispatch]);

  return (
    <>
      <PinCodeContainer
        spotlightId={SpotlightIds.PINCODE_CONTAINER}
        className={css.pinCodeContainer}
      >
        <h1 className={css.pinCodeTitle}>{$L("Enter PIN CODE")}</h1>
        <div className={css.pinCodeBoxes}>
          {pin.map((digit, index) => (
            <div
              key={index}
              className={classNames(css.pinCodeBox, {
                [css.focused]: pin.findIndex((p) => p === "") === index,
              })}
            >
              {digit ? "•" : ""}
            </div>
          ))}
        </div>
        <div className={css.errMsg}>{errorMsg}</div>
        <div className={css.pinCodeDigits}>
          {[...Array(10).keys()].map((digit) => (
            <SpottableButton
              key={digit}
              className={css.pinCodeDigit}
              onClick={() => handleDigitClick(digit.toString())}
            >
              {digit}
            </SpottableButton>
          ))}
          <SpottableButton
            className={classNames(css.pinCodeDigit, css.deleteKey)}
            onClick={handleBackspace}
          />
        </div>
        <div className={css.buttonContainer}>
          <TButton onClick={onClickCancel}>{$L("Cancel")}</TButton>
          <TButton onClick={onClickConfirm}>{$L("OK")}</TButton>
        </div>
      </PinCodeContainer>

      {activePopup === Config.ACTIVE_POPUP.setPinCodePopup && (
        <TPopUp
          kind="setPinCodePopup"
          open={popupVisible}
          hasButton
          button1Text={$L("OK")}
          button2Text={$L("Cancel")}
          onClick={handleClickSetPinCode}
          onClose={handleCancelPopup}
          hasText
          text={$L(
            "The number of PIN CODE errors has been exceeded and the PIN CODE cannot be used. Would you like to set a new PIN CODE?"
          )}
        />
      )}

      {activePopup === Config.ACTIVE_POPUP.qrPopup && (
        <TPopUp kind="qrPopup" open={popupVisible} onClose={handleCancelPopup}>
          <div className={css.popupContainer}>
            <div className={css.header}>
              <h3>{$L("QR CODE")}</h3>
            </div>

            <div className={css.qrcodeContainer}>
              <div className={css.qrcode}>
                <TQRCode text={"http://google.com"} width="360" height="360" />
              </div>
              <h3>
                {$L(
                  "If you want to add or edit your address and payment information, please scan the QR CODE."
                )}
              </h3>
              <TButton className={css.popupBtn} onClick={handleCancelPopup}>
                {$L("CLOSE")}
              </TButton>
            </div>
          </div>
        </TPopUp>
      )}
    </>
  );
}
