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

import classNames from 'classnames';
import {
  AsYouTypeFormatter,
  PhoneNumberFormat,
  PhoneNumberUtil,
} from 'google-libphonenumber';
import { useDispatch, useSelector } from 'react-redux';

import { off, on } from '@enact/core/dispatcher';
import spotlight, { Spotlight } from '@enact/spotlight';
import { SpotlightContainerDecorator } from '@enact/spotlight/SpotlightContainerDecorator';
import { Spottable } from '@enact/spotlight/Spottable';

import defaultImage from '../../../assets/images/img-thumb-empty-144@3x.png';
import { types } from '../../actions/actionTypes';
import { clearSMS, sendSms } from '../../actions/appDataActions';
import {
  changeLocalSettings,
  setHidePopup,
  setShowPopup,
} from '../../actions/commonActions';
import {
  clearRegisterDeviceInfo,
  getDeviceAdditionInfo,
  registerDeviceInfo,
} from '../../actions/deviceActions';
import {
  clearCurationCoupon,
  setEventIssueReq,
} from '../../actions/eventActions';
import {
  sendLogShopByMobile,
  sendLogTotalRecommend,
} from '../../actions/logActions';
import {
  ACTIVE_POPUP,
  LOG_CONTEXT_NAME,
  LOG_MESSAGE_ID,
  LOG_TP_NO,
} from '../../utils/Config';
import {
  $L,
  decryptPhoneNumber,
  encryptPhoneNumber,
  formatLocalDateTime,
} from '../../utils/helperMethods';
import CustomImage from '../CustomImage/CustomImage';
import TButton from '../TButton/TButton';
import TPopUp from '../TPopUp/TPopUp';
import HistoryPhoneNumber from './HistoryPhoneNumber/HistoryPhoneNumber';
import css from './MobileSendPopUp.module.less';
import PhoneInputSection from './PhoneInputSection';
import SMSNumKeyPad from './SMSNumKeyPad';

const SECRET_KEY = 'fy7BTKuM9eeTQqEC9sF3Iw5qG43Aaip';

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

const InputContainer = SpotlightContainerDecorator(
  { enterTo: 'last-focused' },
  'div'
);

const SpottableComponent = Spottable('div');

export default function MobileSendPopUp({
  open,
  onClose,
  title,
  subTitle,
  productImg,
  productPrice,
  brandLogo,
  productId,
  smsTpCd,
  smsText,
  prdtId,
  curationId,
  patnrId,
  evntId,
  evntTpCd,
  isCurationEvnt,
  hotelId,
  hotelNm,
  hotelDtlUrl,
  shopByMobileLogRef,
  spotlightId,
  patncNm,
}) {
  const dispatch = useDispatch();
  const deviceInfo = useSelector((state) => state.device.deviceInfo);
  const { httpHeader } = useSelector((state) => state.common);
  const regDeviceInfoRetCode = useSelector(
    (state) => state.device?.regDeviceInfoData?.retCode
  );
  const smsRetCodeResData = useSelector(
    (state) => state.appData.sendSms?.retCode
  );
  const { phoneNumberList } = useSelector(
    (state) => state.localSettings.phoneNumbers
  );
  const curationCouponSuccess = useSelector(
    (state) => state.event.curationCouponSuccess
  );
  const popupVisible = useSelector((state) => state.common.popup.popupVisible);
  const nowMenu = useSelector((state) => state.common.menu.nowMenu);
  const entryMenu = useSelector((state) => state.common.menu.entryMenu);

  const [inputDisabled, setInputDisabled] = useState(true);
  const [mobileNumber, setMobileNumber] = useState('');
  const [recentSentNumber, setRecentSentNumber] = useState([]);
  const [keyPadOff, setKeyPadOff] = useState(false);
  const [smsRetCode, setSmsRetCode] = useState(undefined);

  const agreeBtnClickedRef = useRef(false);

  const deviceCountryCode = httpHeader['X-Device-Country'];

  const mobileSendPopUpSpotlightId = useMemo(() => {
    return !keyPadOff && recentSentNumber.length <= 0
      ? 'keypad-number-1'
      : 'agreeAndSend';
  }, [keyPadOff, recentSentNumber]);

  const getMaxNum = useCallback((_deviceCountryCode) => {
    if (_deviceCountryCode === 'DE' || _deviceCountryCode === 'GB') {
      return 11;
    } else if (_deviceCountryCode === 'KR') {
      return 12;
    } else return 10;
  }, []);

  const MSG_SUCCESS_SENT = $L('Text Send to') + ' ' + mobileNumber;
  const MSG_SEND_LINK = $L('Send a purchase link for this item via SMS');

  const handleClickSelect = (_phoneNumber) => {
    setKeyPadOff((state) => !state);
    setMobileNumber(_phoneNumber);

    setTimeout(() => {
      Spotlight.focus('keypad-number-1');
    }, 0);
  };

  const handleInputClick = () => {
    setKeyPadOff(false);
    if (recentSentNumber && recentSentNumber.length > 0 && keyPadOff) {
      setMobileNumber(recentSentNumber[0]);
    }
  };

  const getRawPhoneNumber = useCallback(
    (key) => {
      let rawPhoneNumber = `${mobileNumber}${key}`.replace(/\D/g, '');
      if (rawPhoneNumber.length === getMaxNum(deviceCountryCode)) {
        Spotlight.focus('agreeAndSend');
      }
      // 테스트용: 12자리까지 허용
      if (rawPhoneNumber.length > 12) {
        return;
      }
      const phoneUtil = PhoneNumberUtil.getInstance();
      const asYouTypeFormatter = new AsYouTypeFormatter(deviceCountryCode);

      try {
        let numberProto = phoneUtil.parse(rawPhoneNumber, deviceCountryCode);
        if (
          phoneUtil.isValidNumber(numberProto) &&
          phoneUtil.isValidNumberForRegion(numberProto, deviceCountryCode)
        ) {
          rawPhoneNumber = phoneUtil.format(
            numberProto,
            PhoneNumberFormat.NATIONAL
          );
          if (deviceCountryCode === 'RU' && rawPhoneNumber.startsWith('8')) {
            rawPhoneNumber = rawPhoneNumber.substring(1);
          }
        } else {
          let formattedNumber = '';

          for (let i = 0; i < rawPhoneNumber.length; i++) {
            formattedNumber = asYouTypeFormatter.inputDigit(
              Number(rawPhoneNumber[i])
            );
          }

          rawPhoneNumber = formattedNumber;
        }
      } catch (e) {
        rawPhoneNumber = `${mobileNumber}${key}`;
      } finally {
        setMobileNumber(rawPhoneNumber);
      }
    },
    [mobileNumber, deviceCountryCode]
  );

  const getBackspaceRawNumber = useCallback(() => {
    let rawPhoneNumber = mobileNumber.replace(/\D/g, '').slice(0, -1);
    const phoneUtil = PhoneNumberUtil.getInstance();
    const asYouTypeFormatter = new AsYouTypeFormatter(deviceCountryCode);

    try {
      let numberProto = phoneUtil.parse(rawPhoneNumber, deviceCountryCode);
      if (
        phoneUtil.isValidNumber(numberProto) &&
        phoneUtil.isValidNumberForRegion(numberProto, deviceCountryCode)
      ) {
        rawPhoneNumber = phoneUtil.format(
          numberProto,
          PhoneNumberFormat.NATIONAL
        );
      } else {
        let formattedNumber = '';

        for (let i = 0; i < rawPhoneNumber.length; i++) {
          formattedNumber = asYouTypeFormatter.inputDigit(
            Number(rawPhoneNumber[i])
          );
        }

        rawPhoneNumber = formattedNumber;
      }
    } catch (e) {
      rawPhoneNumber = mobileNumber.slice(0, -1);
    } finally {
      setMobileNumber(rawPhoneNumber);
    }
  }, [mobileNumber, deviceCountryCode]);

  const handleKeydown = useCallback(
    (ev) => {
      if (ev && ev.key >= 0 && ev.key <= 9) {
        getRawPhoneNumber(ev.key);
      } else if (ev.key === 'Backspace') {
        getBackspaceRawNumber();
      }
    },
    [mobileNumber]
  );

  useEffect(() => {
    on('keydown', handleKeydown);
    return () => {
      off('keydown', handleKeydown);
    };
  }, [handleKeydown]);

  useEffect(() => {
    if (!deviceInfo) {
      dispatch(getDeviceAdditionInfo());
    }
  }, [deviceInfo, dispatch]);

  useEffect(() => {
    const timer = setTimeout(() =>
      setInputDisabled(mobileSendPopUpSpotlightId === 'keypad-number-1')
    );

    return () => clearTimeout(timer);
  }, [mobileSendPopUpSpotlightId]);

  useEffect(() => {
    if (!agreeBtnClickedRef.current && recentSentNumber) {
      if (recentSentNumber.length > 0) {
        setKeyPadOff(true);
        setMobileNumber(recentSentNumber[0]);
      } else {
        setKeyPadOff(false);
        setMobileNumber('');
      }
    }
  }, [recentSentNumber]);

  const numKeypadClicked = useCallback(
    (key) => {
      if (key === 'clear') {
        setMobileNumber('');
      } else if (key == 'backspace') {
        getBackspaceRawNumber();
      } else {
        getRawPhoneNumber(key);
      }
    },
    [deviceCountryCode, mobileNumber]
  );

  const handleDelete = (selectedIndex) => {
    if (recentSentNumber) {
      const updateItems = recentSentNumber.filter(
        (_, index) => index !== selectedIndex
      );
      setRecentSentNumber(updateItems);

      const encryptedNumbers = updateItems.map(encryptPhoneNumber);

      dispatch(
        changeLocalSettings({
          phoneNumbers: {
            phoneNumberList: encryptedNumbers,
          },
        })
      );
    }
  };

  const handleAgreeSendClick = useCallback(() => {
    let naturalNumber = mobileNumber.replace(/\D/g, '');

    // 테스트용: 길이 체크를 더 유연하게 (10자리 또는 11자리 허용)
    if (
      !mobileNumber ||
      naturalNumber.length < 10 ||
      naturalNumber.length > 12
    ) {
      setSmsRetCode(907);
      return;
    }

    if (deviceCountryCode === 'KR') {
      naturalNumber = '82' + naturalNumber;
    }

    if (recentSentNumber && recentSentNumber.length > 0) {
      const updatedNumbers = [...recentSentNumber];

      const existingNumberIndex = updatedNumbers.findIndex(
        (existingNum) => existingNum === mobileNumber
      );
      if (existingNumberIndex !== -1) {
        updatedNumbers.splice(existingNumberIndex, 1);
      }

      if (updatedNumbers.length >= 5) {
        updatedNumbers.pop();
      }

      updatedNumbers.unshift(mobileNumber);
      agreeBtnClickedRef.current = true;
      setRecentSentNumber(updatedNumbers);

      const encryptedNumbers = updatedNumbers.map(encryptPhoneNumber);

      dispatch(
        changeLocalSettings({
          phoneNumbers: {
            phoneNumberList: encryptedNumbers,
          },
        })
      );
    } else {
      setRecentSentNumber([mobileNumber]);
      dispatch(
        changeLocalSettings({
          phoneNumbers: {
            phoneNumberList: [encryptPhoneNumber(mobileNumber)],
          },
        })
      );
    }

    if (isCurationEvnt) {
      dispatch(
        setEventIssueReq({
          evntTpCd,
          evntId,
          mbphNo: naturalNumber,
          cntryCd: deviceCountryCode,
        })
      );
      return;
    }
    if (deviceInfo && smsTpCd) {
      let params = {
        dvcIndex: deviceInfo.dvcIndex,
        mbphNo: naturalNumber,
        smsTpCd,
        patnrId,
        evntId,
        curationId,
        smsText,
        prdtId,
        entryMenu: nowMenu,
      };

      // 호텔일 경우 날려야 하는 경우
      if (smsTpCd === 'APP00205') {
        params = { ...params, hotelId, hotelNm, hotelDtlUrl, curationId };
      }
      if (smsTpCd === 'APP00204') {
        params = { ...params, curationId };
      }
      dispatch(sendSms(params));
    }
    // EVT00101 & APP00207(welcome) EVT00103 & APP00209 (welcome+Prizes) : smsTpCd 값을 받지 않음
    if (evntTpCd === 'EVT00101' || evntTpCd === 'EVT00103') {
      dispatch(
        registerDeviceInfo({
          evntTpCd,
          evntId,
          evntApplcnFlag: 'Y',
          entryMenu: 'TermsPop',
          mbphNo: naturalNumber,
        })
      );
    }
  }, [
    dispatch,
    mobileNumber,
    smsTpCd,
    evntTpCd,
    deviceInfo,
    deviceCountryCode,
    nowMenu,
  ]);

  const _onClose = useCallback(
    (e) => {
      if (e.target) {
        dispatch(clearSMS());
        dispatch(clearCurationCoupon());
        setSmsRetCode(undefined);
      }
      onClose();
      dispatch(setShowPopup(ACTIVE_POPUP.smsPopup));

      setTimeout(() => Spotlight.focus('agreeAndSend'));
    },
    [dispatch, smsRetCode]
  );

  useEffect(() => {
    setSmsRetCode(smsRetCodeResData);

    let timer;

    if (
      smsRetCodeResData === 0 ||
      regDeviceInfoRetCode === 0 ||
      curationCouponSuccess === 0
    ) {
      const logParams = {
        status: 'send',
        nowMenu: nowMenu,
        partner: patncNm ?? shopByMobileLogRef?.current?.patncNm,
        productId: prdtId ?? shopByMobileLogRef?.current?.prdtId,
        productTitle: title ?? shopByMobileLogRef?.current?.prdtNm,
        brand: shopByMobileLogRef?.current?.brndNm,
        contextName: LOG_CONTEXT_NAME.SHOPBYMOBILE,
        messageId: LOG_MESSAGE_ID.SMB,
      };
      dispatch(sendLogTotalRecommend(logParams));
      if (shopByMobileLogRef) {
        let params = {
          ...shopByMobileLogRef.current,
          locDt: formatLocalDateTime(new Date()),
          logTpNo: LOG_TP_NO.SHOP_BY_MOBILE.AGREE_AND_SEND,
          mbphNoFlag: 'Y',
          trmsAgrFlag: 'Y',
        };

        dispatch(sendLogShopByMobile(params));
        shopByMobileLogRef.current = null;
      }

      if (spotlightId) Spotlight.focus(spotlightId);
      else Spotlight.focus();

      return () => clearTimeout(timer);
    }
  }, [
    shopByMobileLogRef,
    smsRetCodeResData,
    regDeviceInfoRetCode,
    curationCouponSuccess,
    spotlightId,
  ]);

  useEffect(() => {
    // retCode initialize
    return () => {
      dispatch(clearSMS());
      dispatch(clearRegisterDeviceInfo());
      dispatch(clearCurationCoupon());
      dispatch(setHidePopup());
    };
  }, [dispatch]);

  const getSmsErrorMsg = useMemo(() => {
    const SMS_ERROR_502 = $L('The event information has not been registered');
    const SMS_ERROR_903 = $L('You have exceeded the daily text limit.');
    const SMS_ERROR_904 = $L(
      'You have exceeded the text limit for this product.'
    );
    const SMS_ERROR_905 = $L(
      'This number is currently blocked. To receive a message, please send UNSTOP to the number below. 07860 064195'
    );
    const SMS_ERROR_906 = $L('Sorry. This item is sold out.');
    const SMS_ERROR_600 = $L('This device had received first time coupon.');
    const SMS_ERROR_601 = $L('There is no coupon.');
    const SMS_ERROR_900 = $L('Failed to send text to {mobileNumber}').replace(
      '{mobileNumber}',
      mobileNumber
    );
    const SMS_ERROR_907 = $L(
      'Only {length} digits is permitted. Please check again'
    ).replace('{length}', getMaxNum(deviceCountryCode));

    switch (smsRetCode) {
      case 502:
        return SMS_ERROR_502;
      case 600:
        return SMS_ERROR_600;
      case 601:
        return SMS_ERROR_601;
      case 900:
        return SMS_ERROR_900;
      case 903:
        return SMS_ERROR_903;
      case 904:
        return SMS_ERROR_904;
      case 905:
        return SMS_ERROR_905;
      case 906:
        return SMS_ERROR_906;
      case 907:
        return smsRetCodeResData === 907 ? SMS_ERROR_900 : SMS_ERROR_907;
      default:
        return SMS_ERROR_900;
    }
  }, [smsRetCode, mobileNumber, smsRetCodeResData]);

  const getEvntErrorMsg = useMemo(() => {
    if (curationCouponSuccess === 600) {
      return $L('This device had received first time coupon.');
    } else if (curationCouponSuccess === 601) {
      return $L('There is no coupon.');
    } else {
      return $L('Failed to sent text to {mobileNumber}').replace(
        '{mobileNumber}',
        mobileNumber
      );
    }
  }, [curationCouponSuccess, mobileNumber]);

  const retCodeError =
    (smsRetCode !== undefined && smsRetCode !== 0) ||
    (curationCouponSuccess !== undefined && curationCouponSuccess !== 0);

  useEffect(() => {
    if (phoneNumberList) {
      const decryptedNumbers = phoneNumberList.map(decryptPhoneNumber);
      setRecentSentNumber(decryptedNumbers);
    }
  }, [phoneNumberList]);

  return (
    <>
      {smsRetCode === undefined &&
        open &&
        regDeviceInfoRetCode === undefined &&
        curationCouponSuccess === undefined && (
          <TPopUp
            kind={'mobileSendPopup'}
            className={css.container}
            open={open}
            onClose={onClose}
            hasText
            spotlightId={mobileSendPopUpSpotlightId}
          >
            <div className={css.titleHead}>
              <div className={css.titleHead__text}>
                {title || MSG_SEND_LINK}
              </div>
            </div>
            <div className={css.container__header}>
              {productImg && (
                <p className={css.container__header__productImg}>
                  <CustomImage
                    className={css.container__header__productImg__img}
                    src={productImg}
                    fallbackSrc={defaultImage}
                  />
                </p>
              )}
              <div
                className={classNames(
                  css.container__header__textBox,
                  !productImg && css.container__header__textBoxOnly
                )}
              >
                <div className={css.headerTopRow}>
                  {brandLogo && (
                    <img
                      className={classNames(
                        css.headerTopRow__brandLogo,
                        patnrId === '1' && css.headerTopRow__brandLogo__qvc
                      )}
                      src={brandLogo}
                      alt="Brand"
                    />
                  )}
                  {productId && patnrId !== '21' && (
                    <div className={css.headerTopRow__productId}>
                      ID: {productId}
                    </div>
                  )}
                  {patnrId === '21' && (
                    <div className={css.headerTopRow__productId}>{patncNm}</div>
                  )}
                </div>
                {subTitle && (
                  <div
                    className={classNames(
                      css.container__header__subTitle,
                      !productImg && css.container__header__subTitleOnly
                    )}
                  >
                    {subTitle}
                  </div>
                )}
                {productPrice && (
                  <div className={css.container__header__price}>
                    {productPrice}
                  </div>
                )}
              </div>
            </div>
            <div className={css.container__smsArea}>
              {/* 🔄 [BACKUP] 기존 전화번호 입력 영역 - 원상복구용 */}
              <div className={css.container__smsArea__smsContainer}>
                <InputContainer className={css.smsNumLayer}>
                  <SpottableComponent
                    className={css.inputNum}
                    onClick={handleInputClick}
                    spotlightDisabled={inputDisabled}
                  >
                    {deviceCountryCode && deviceCountryCode === 'RU' && (
                      <span className={css.rucInput}>{'+7 '}</span>
                    )}
                    <span>{mobileNumber}</span>
                  </SpottableComponent>
                </InputContainer>
                <Container className={css.flex}>
                  {keyPadOff && recentSentNumber.length > 0 ? (
                    <HistoryPhoneNumber
                      handleClickSelect={handleClickSelect}
                      handleDelete={handleDelete}
                      recentSentNumber={recentSentNumber}
                    />
                  ) : (
                    <SMSNumKeyPad onKeyDown={numKeypadClicked} />
                  )}
                </Container>
              </div>
              <div className={css.instruction}>
                {deviceCountryCode && (
                  <span
                    dangerouslySetInnerHTML={{
                      __html: `${$L(
                        'By clicking Agree and Send button, I agree that LGE may collect and store my cell phone number to send text messages as I requested, for data analysis and for feature-enhancement purposes. By entering my cell phone number, I agree to receive messages from LGE with information on how to purchase the product I selected. Message and data rates may apply.'
                      )}`,
                    }}
                    className={deviceCountryCode === 'RU' && css.instructionRu}
                  />
                )}
              </div>

              {/* 🆕 [NEW] PhoneInputSection + instruction 좌우 배치 */}
              {/* <div className={css.container__smsArea__smsContainer}>
                <PhoneInputSection
                  mobileNumber={mobileNumber}
                  deviceCountryCode={deviceCountryCode}
                  onInputClick={handleInputClick}
                  onKeypadClick={numKeypadClicked}
                  spotlightId={mobileSendPopUpSpotlightId}
                  inputDisabled={inputDisabled}
                />
              </div>
              <div className={css.container__smsArea__instruction}>
                {deviceCountryCode && (
                  <div className={deviceCountryCode === "RU" ? css.instructionRu : ""}>
                    <div>
                      {$L("By clicking Agree and Send button, I agree that LGE may collect and store my cell phone number to send text messages as I requested, for data analysis and for feature-enhancement purposes.")}
                    </div>
                    <div style={{ height: "16px" }}></div>
                    <div>
                      {$L("By entering my cell phone number, I agree to receive messages from LGE with information on how to purchase the product I selected. Message and data rates may apply.")}
                    </div>
                  </div>
                )}
              </div>               */}
            </div>
            <Container className={css.container__btnContainer}>
              <TButton
                onClick={handleAgreeSendClick}
                spotlightId={'agreeAndSend'}
              >
                {$L('Agree and Send')}
              </TButton>
              <TButton onClick={onClose}>{$L('Cancel')}</TButton>
            </Container>
          </TPopUp>
        )}
      {retCodeError && (
        <TPopUp
          kind="textPopup"
          open={popupVisible}
          hasText
          text={smsTpCd ? getSmsErrorMsg : getEvntErrorMsg}
          onClick={_onClose}
          hasButton
          button1Text={$L('OK')}
        />
      )}
      {(smsRetCode === 0 ||
        regDeviceInfoRetCode === 0 ||
        regDeviceInfoRetCode === 0) && (
        <TPopUp
          kind="textPopup"
          open={popupVisible}
          hasText
          text={MSG_SUCCESS_SENT}
          onClick={onClose}
          hasButton
          button1Text={$L('OK')}
        />
      )}
    </>
  );
}
