import React, {
  // useMemo,
  useCallback,
  useEffect,
  useRef,
  // useState,
} from "react";
import { useSelector, useDispatch } from "react-redux";
// import { I18nContext } from "@enact/i18n";
// import classNames from "classnames";
// import PropTypes from "prop-types";
import Spotlight from "@enact/spotlight";
import { Job } from "@enact/core/util";
import platform from "@enact/core/platform";
import { ThemeDecorator } from "@enact/sandstone/ThemeDecorator";

// import "../../../assets/fontello/css/fontello.css";

import {
  changeAppStatus,
  changeLocalSettings,
  // cancelFocusElement,
  // focusElement,
  // setExitApp,
  // setPreventMouse,
  // setShowPopup,
  // setTermsAgreeYn,
  getTermsAgreeYn,
  deleteOldDb8Datas,
  sendBroadCast,
  getConnectionStatus,
  getConnectionInfo,
  getDeviceId,
  getHttpHeaderForServiceRequest,
  getSystemSettings,
  checkFirstLaunch,
  setDeepLink,
  setGNBMenu,
  setSecondLayerInfo,
} from "../actions/commonActions";
import { getShoptimeTerms } from "../actions/empActions";
import { getHomeMenu, getHomeTerms } from "../actions/homeActions";
import {
  getMyRecommandedKeyword,
  getMyUpcomingAlertShow,
} from "../actions/myPageActions";
import { pushPanel } from "../actions/panelActions";
import NotSupportedVersion from "../components/NotSupportedVersion/NotSupportedVersion";
import usePrevious from "../hooks/usePrevious";
import { lunaTest } from "../lunaSend/lunaTest";
import { store } from "../store/store";
import * as Config from "../utils/Config";
import {
  // $L,
  clearLaunchParams,
  // getCountry,
  getLaunchParams,
  // getUUID,
  // resizeTo,
} from "../utils/helperMethods";
import { SpotlightIds } from "../utils/SpotlightIds";
import ErrorBoundary from "../views/ErrorBoundary";
import MainView from "../views/MainView/MainView";
import css from "./App.module.less";
import { handleBypassLink } from "./bypassLinkHandler";
import { handleDeepLink } from "./deepLinkHandler";
import { sendLogTotalRecommend } from "../actions/logActions";
// import {
// startFocusMonitoring,
// stopFocusMonitoring,
// } from "../utils/focus-monitor";
// import { PanelHoc } from "../components/TPanel/TPanel";



let foreGroundChangeTimer = null;

// 기존 콘솔 메서드를 백업
const originalConsole = {
  log: console.log,
  error: console.error,
  warn: console.warn,
  info: console.info,
};
const enableConsole = () => {
  console.log = originalConsole.log;
  console.error = originalConsole.error;
  console.warn = originalConsole.warn;
  console.info = originalConsole.info;
};
const disableConsole = () => {
  console.log = function () {};
  // console.error = function() {};
  console.warn = function () {};
  console.info = function () {};
};

const originFocus = Spotlight.focus;
Spotlight.focus = function (elem, containerOption) {
  const ret = originFocus.apply(this, [elem, containerOption]); // this 바인딩을 유지하여 originFocus 호출
  if (ret === true) {
    const current = Spotlight.getCurrent();
    const floatLayerNode = document.getElementById("floatLayer");
    const tabLayoutNode = document.getElementById(SpotlightIds.TAB_LAYOUT);
    //팝업이 존재할 경우
    if (floatLayerNode && floatLayerNode.childElementCount > 0) {
      if (!floatLayerNode.contains(current)) {
        if (floatLayerNode.lastElementChild) {
          const spottableNode = floatLayerNode.lastElementChild.querySelector(
            '[data-spotlight-container="true"]'
          );
          if (spottableNode) {
            originFocus.apply(this, [spottableNode]); // this 바인딩을 유지하여 originFocus 호출
          }
        }
      }
    } else {
      //GNB가 열린 상태에서 Panel에 포커스 가는 경우
      if (
        current &&
        store.getState().common.isGnbOpened &&
        !tabLayoutNode.contains(current)
      ) {
        store.dispatch(
          sendBroadCast({
            type: "deActivateTab",
            moreInfo: { reason: "focus" },
          })
        );
      }
    }
  }
  return ret;
};

function AppBase(props) {
  const dispatch = useDispatch();
  const httpHeader = useSelector((state) => state.common.httpHeader);
  const httpHeaderRef = useRef(httpHeader);
  const webOSVersion = useSelector(
    (state) => state.common.appStatus.webOSVersion
  );
  const deviceId = useSelector((state) => state.common.appStatus.deviceId);
  const loginUserData = useSelector(
    (state) => state.common.appStatus.loginUserData
  );
  const loginUserDataRef = useRef(loginUserData);
  const cursorVisible = useSelector(
    (state) => state.common.appStatus.cursorVisible
  );
  const introTermsAgree = useSelector((state) => state.common.introTermsAgree);
  const deviceRegistered = useSelector((state) => state.common.deviceRegistered);
  // const optionalTermsAgree = useSelector((state) => state.common.optionalTermsAgree);
  const termsLoading = useSelector((state) => state.common.termsLoading);
  // termsFlag 전체 상태 확인
  // const termsFlag = useSelector((state) => state.common.termsFlag);
  const termsData = useSelector((state) => state.home.termsData);



  useEffect(() => {
    // Chromium68 호환성을 위해 Optional Chaining 제거
    if (termsData && termsData.data && termsData.data.terms) {
      dispatch(getTermsAgreeYn());
    }
  }, [termsData, dispatch]);

  const introTermsAgreeRef = usePrevious(introTermsAgree);
  const logEnable = useSelector((state) => state.localSettings.logEnable);
  const oldDb8Deleted = useSelector(
    (state) => state.localSettings.oldDb8Deleted
  );
  // const macAddress = useSelector((state) => state.common.macAddress);

  // Chromium68 호환성을 위해 Optional Chaining 제거
  const deviceCountryCode = httpHeader && httpHeader["X-Device-Country"] || "";

  useEffect(() => {
    if (!cursorVisible && !Spotlight.getCurrent()) {
      Spotlight.focus();
    }
  }, [cursorVisible]);

  useEffect(() => {
    if (logEnable) {
      enableConsole();
    } else {
      disableConsole();
    }
  }, [logEnable]);

  useEffect(() => {
    if (!oldDb8Deleted) {
      dispatch(deleteOldDb8Datas());
    }
  }, [oldDb8Deleted, dispatch]);

  const hideCursor = useRef(
    new Job((func) => {
      func();
      console.log("hide cursor");
    }, 5000)
  );

  // 컴포넌트에서 모니터링 시작 - 한시적 모니터링
  // useEffect(() => {
  //   startFocusMonitoring();
  //   return () => stopFocusMonitoring();
  // }, []);

  // 임시 작업용 코드 -> 인트로 팝업 표시
  // useEffect(() => {
  //   const timer = setTimeout(() => {
  //     dispatch(
  //       pushPanel({ name: Config.panel_names.INTRO_PANEL, panelInfo: {} })
  //     );
  //   }, 1000);

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

  // called by [receive httpHeader, launch, relaunch]
  const initService = useCallback(
    
    (haveyInit = true) => {
     
      // console.log(
      //   "<<<<<<<<<<<<<        appinfo      >>>>>>>>>>>>{heavyInit,  appinfo} ",
      //   haveyInit,
      //   appinfo
      // );

      console.log(
        "[App.js] initService,httpHeaderRef.current",
        httpHeaderRef.current
      );
      console.log("[App.js] haveyInit", haveyInit);

      if (httpHeaderRef.current) {
        if (haveyInit) {
          dispatch(changeAppStatus({ connectionFailed: false }));
          if (typeof window === "object" && window.PalmSystem) {
                    dispatch(
          changeAppStatus({
            // Chromium68 호환성을 위해 Optional Chaining 제거
            cursorVisible: window.PalmSystem && window.PalmSystem.cursor && window.PalmSystem.cursor.visibility,
          })
        );
          }
          dispatch(getHomeMenu());
          dispatch(getMyRecommandedKeyword());
          dispatch(getMyUpcomingAlertShow());
        }

        const launchParams = getLaunchParams();

        console.log(
          "initService...{haveyInit, launchParams}",
          haveyInit,
          JSON.stringify(launchParams)
        );

        // pyh TODO: edit or delete later (line 196 ~  198)
        // Chromium68 호환성을 위해 Optional Chaining 제거
        if (launchParams && launchParams.bypass) {
          dispatch(handleBypassLink(launchParams.bypass));
        }
        if (launchParams && launchParams.contentTarget) {
          dispatch(handleDeepLink(launchParams.contentTarget));
        } else {
          dispatch(
            sendLogTotalRecommend({
              contextName: Config.LOG_CONTEXT_NAME.ENTRY,
              messageId: Config.LOG_MESSAGE_ID.ENTRY_INFO,
              entry_menu: "App",
            })
          );
        }

        dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
        dispatch(
          sendLogTotalRecommend({
            contextName: Config.LOG_CONTEXT_NAME.SHOPTIME,
            messageId: Config.LOG_MESSAGE_ID.VIEW_CHANGE,
            visible: true,
          })
        );
        clearLaunchParams();
      }
    },
    [dispatch]
  );

  const handleRelaunchEvent = useCallback(() => {
    console.log("handleRelaunchEvent started");
    if (introTermsAgreeRef.current) {
      initService(false);
    }
    if (typeof window === "object" && window.PalmSystem) {
      window.PalmSystem.activate();
    }
  }, [initService, introTermsAgreeRef]);

  const visibilityChanged = useCallback(() => {
    console.log("document is hidden", document.hidden);
    console.log("document.visibilityState= ", document.visibilityState);
    if (document.hidden && typeof window === "object") {
      clearTimeout(foreGroundChangeTimer);
    } else {
      // change to foreground
      // set foreground flag using delay time.
      clearTimeout(foreGroundChangeTimer);
      foreGroundChangeTimer = setTimeout(() => {
                  console.log(
            "visibility changed !!! ==> set to foreground cursorVisible",
            // Chromium68 호환성을 위해 Optional Chaining 제거
            JSON.stringify(window.PalmSystem && window.PalmSystem.cursor && window.PalmSystem.cursor.visibility)
          ); // eslint-disable-line no-console
        if (platform.platformName !== "webos") {
          //for debug
          dispatch(
            changeAppStatus({
              isAppForeground: true,
              cursorVisible: !platform.touchscreen,
            })
          );
        } else if (typeof window === "object") {
          dispatch(
            changeAppStatus({
              isAppForeground: true,
              // Chromium68 호환성을 위해 Optional Chaining 제거
              cursorVisible: window.PalmSystem && window.PalmSystem.cursor && window.PalmSystem.cursor.visibility,
            })
          );
        }
      }, 1000);
    }
  }, [dispatch]);

  useEffect(() => {
    const keyDownEvent = (event) => {
      dispatch(changeAppStatus({ cursorVisible: false }));
      Spotlight.setPointerMode(false);
    };
    const mouseMoveEvent = (event) => {
      dispatch(changeAppStatus({ cursorVisible: true }));
      Spotlight.setPointerMode(true);
      hideCursor.current.start(() => {
        dispatch(changeAppStatus({ cursorVisible: false }));
        Spotlight.setPointerMode(false);
      });
    };
    if (typeof window === "object" && window.PalmSystem) {
      window.PalmSystem.activate();
      window.lunaTest = (service, method, subscribe, parameters) =>
        lunaTest(service, method, subscribe, parameters);
    }

    dispatch(getConnectionStatus());
    dispatch(getConnectionInfo());
    dispatch(getDeviceId());
    dispatch(getHttpHeaderForServiceRequest());
    dispatch(getSystemSettings());
    document.addEventListener("visibilitychange", visibilityChanged);
    document.addEventListener("webOSRelaunch", handleRelaunchEvent);
    //local virtual cursorvisiblilty
    if (typeof window === "object" && !window.PalmSystem) {
      document.addEventListener("keydown", keyDownEvent, true);
      document.addEventListener("mousemove", mouseMoveEvent, true);
      document.addEventListener("wheel", mouseMoveEvent, true);
    }
    return () => {
      document.removeEventListener("visibilitychange", visibilityChanged);
      document.removeEventListener("webOSRelaunch", handleRelaunchEvent);
      if (typeof window === "object" && !window.PalmSystem) {
        document.removeEventListener("keydown", keyDownEvent);
        document.removeEventListener("mousemove", mouseMoveEvent);
        document.removeEventListener("wheel", mouseMoveEvent);
      }
    };
  }, [dispatch, visibilityChanged, handleRelaunchEvent]);

  useEffect(() => {
    let userDataChanged = false;
    if (
      JSON.stringify(loginUserDataRef.current) !== JSON.stringify(loginUserData)
    ) {
      userDataChanged = true;
    }
    if (!httpHeader || !deviceId) {
    } else if (userDataChanged || httpHeaderRef.current === null) {
      //계정정보 변경시 또는 초기 로딩시
      if (!httpHeader) {
        dispatch(
          changeAppStatus({
            showLoadingPanel: { show: true, type: "launching" },
          })
        );
      }
      dispatch(checkFirstLaunch());

      dispatch(
        getHomeTerms({
          mbrNo: loginUserData.userNumber,
          trmsTpCdList: "MST00401, MST00402, MST00405", // 선택약관 추가 25.06
        })
      );

      httpHeaderRef.current = httpHeader;
    }
    loginUserDataRef.current = loginUserData;
  }, [httpHeader, deviceId, dispatch, loginUserData]);

  useEffect(() => {
    if (
      webOSVersion &&
      Number(webOSVersion) >= 6 &&
      deviceCountryCode &&
      deviceCountryCode === "US" &&
      deviceId
    ) {
      dispatch(getShoptimeTerms());
    }
  }, [webOSVersion, deviceId, dispatch, deviceCountryCode]);

  // 테스트용 인트로 화면 표시
  // useEffect(() => {
  //   setTimeout(() => {
  //     console.log("App.js optionalTermsTest 팝업 표시");
  //     dispatch(setShowPopup({ activePopup: "optionalTermsConfirmBottom" }));
  //   }, 1000);
  // }, [dispatch]);

  // 약관 동의 및 선택 약관 팝업 처리
  useEffect(() => {
    if (introTermsAgree === undefined || termsLoading) {
      // 약관 동의 여부 확인 전에는 아무것도 하지 않음
      return;
    }
    console.log("[App.js] deviceRegistered", deviceRegistered);
    if (introTermsAgree || deviceRegistered) {
      initService(true);
    } else {
      // 필수 약관에 동의하지 않은 경우
      dispatch(
        pushPanel({ name: Config.panel_names.INTRO_PANEL, panelInfo: {} })
      );
      dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
    }
  }, [introTermsAgree, deviceRegistered, dispatch, initService, termsLoading]);

  useEffect(() => {
    const launchParmas = getLaunchParams();
    const linkTpNm = launchParmas.contentTarget
      ? launchParmas.contentTarget.split("_")[2] || ""
      : Config.LOG_MENU.APP;
    const linkTpCd = launchParmas.contentTarget
      ? launchParmas.contentTarget.split("_")[1] || ""
      : "1000";

    if (launchParmas.contentTarget) {
      dispatch(
        setDeepLink({
          contentTarget: launchParmas.contentTarget,
          isDeepLink: true,
        })
      );
    }

    dispatch(setGNBMenu(linkTpNm));
    dispatch(
      setSecondLayerInfo({
        deeplinkId: launchParmas.contentTarget ?? "",
        linkTpCd,
        logTpNo: Config.LOG_TP_NO.SECOND_LAYER,
      })
    );
  }, [dispatch, initService]);

  return (
    <ErrorBoundary>
      {webOSVersion === "" ? null : Number(webOSVersion) < 4 ? (
        <NotSupportedVersion />
      ) : (
        <MainView
          initService={initService}
          className={
            typeof window === "object" &&
            !window.PalmSystem &&
            !cursorVisible &&
            css.preventMouse
          }
        />
      )}
    </ErrorBoundary>
  );
}

const App = ThemeDecorator({ noAutoFocus: true }, AppBase);

export default App;
export { App, AppBase };
