import React, { use, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import classNames from 'classnames';
import { indexOf } from 'ilib/lib/JSUtils';
import { useDispatch, useSelector } from 'react-redux';
import platform from '@enact/core/platform';
import Spotlight from '@enact/spotlight';
import defaultWatchItem from '../../../assets/images/img-alert-banner-st@3x.png';
// 테스트용 - TODO: 메인 홈 화면에 나와야 하는 이미지들 추가 후 preloadImages에 추가
// import testImage from '../../../assets/images/img-banner-myinfo-login@3x.png';
// import defaultImageItem from '../../../assets/images/img-thumb-empty-product@3x.png';
import LoadingPreloadImage from '../../../assets/images/intro/splash_02_stop.webp';
import LoadingAnimation from '../../../assets/images/intro/splash_03_end.webp';
import LoadingCompleteImage from '../../../assets/images/intro/splash_04_end.webp';
import LoadingShopOnTvImage from '../../../assets/images/intro/splash_end.jpg';
import {
alertToast,
changeAppStatus,
changeLocalSettings,
clearErrorMessage,
setExitApp,
setHidePopup,
setShowPopup,
} from '../../actions/commonActions';
import { getHomeMenu, getHomeTerms, updateHomeInfo } from '../../actions/homeActions';
import {
sendLogAlarmClick,
sendLogAlarmPop,
sendLogLive,
sendLogVOD,
} from '../../actions/logActions';
import { getMyUpcomingAlertShow, setMyTermsWithdraw } from '../../actions/myPageActions';
import { popPanel, pushPanel, resetPanels, updatePanel } from '../../actions/panelActions';
import EndOfServicePopUp from '../../components/EndOfServicePopUp/EndOfServicePopUp';
import Loader from '../../components/Loader/Loader';
import { convertUtcToLocal } from '../../components/MediaPlayer/util';
import OptionalTermsConfirm from '../../components/Optional/OptionalTermsConfirm';
import OptionalTermsConfirmBottom from '../../components/Optional/OptionalTermsConfirmBottom';
import PreloadImage from '../../components/PreloadImage/PreloadImage';
import SystemNotification from '../../components/SystemNotification/SystemNotification';
import TabLayout from '../../components/TabLayout/TabLayout';
import TButton from '../../components/TButton/TButton';
import TNewPopUp from '../../components/TPopUp/TNewPopUp';
import TPopUp from '../../components/TPopUp/TPopUp';
import usePrevious from '../../hooks/usePrevious';
import * as Config from '../../utils/Config';
import { panel_names, STANDALONE_PANELS, isStandalonePanel } from '../../utils/Config';
import { $L, getErrorMessage, getSpottableDescendants } from '../../utils/helperMethods';
import { BUYNOW_CONFIG } from '../../utils/BuyNowConfig';
import { SpotlightIds } from '../../utils/SpotlightIds';
import CartPanel from '../CartPanel/CartPanel';
import CategoryPanel from '../CategoryPanel/CategoryPanel';
import CheckOutPanel from '../CheckOutPanel/CheckOutPanel';
import ConfirmPanel from '../ConfirmPanel/ConfirmPanel';
import DebugPanel from '../DebugPanel/DebugPanel';
import DetailPanel from '../DetailPanel/DetailPanel';
import ErrorPanel from '../ErrorPanel/ErrorPanel';
import FeaturedBrandsPanel from '../FeaturedBrandsPanel/FeaturedBrandsPanel';
import HomePanel from '../HomePanel/HomePanel';
import HotPicksPanel from '../HotPicksPanel/HotPicksPanel';
import ImagePanel from '../ImagePanel/ImagePanel';
import IntroPanel from '../IntroPanel/IntroPanel.new';
import JustForYouPanel from '../JustForYouPanel/JustForYouPanel';
import JustForYouTestPanel from '../JustForYouTestPanel/JustForYouTestPanel';
import LoadingPanel from '../LoadingPanel/LoadingPanel';
import MediaPanel from '../MediaPanel/MediaPanel.v3';
import MyPagePanel from '../MyPagePanel/MyPagePanel';
import OnSalePanel from '../OnSalePanel/OnSalePanel';
import PlayerPanel from '../PlayerPanel/PlayerPanel';
import SearchPanel from '../SearchPanel/SearchPanel.new.v2';
/* VUI_DISABLE_START - VoicePanel import 비활성화 */
// import VoicePanel from '../VoicePanel/VoicePanel';
/* VUI_DISABLE_END */
import ThemeCurationPanel from '../ThemeCurationPanel/ThemeCurationPanel';
import TrendingNowPanel from '../TrendingNowPanel/TrendingNowPanel';
import UserReviewPanel from '../UserReview/UserReviewPanel';
import WelcomeEventPanel from '../WelcomeEventPanel/WelcomeEventPanel';
import css from './MainView.module.less';
// DEBUG_MODE 상수 - true일 때만 console.log 출력
const DEBUG_MODE = false;
const preloadImages = [
LoadingPreloadImage,
LoadingAnimation,
LoadingCompleteImage,
LoadingShopOnTvImage,
];
const panelMap = {
[Config.panel_names.INTRO_PANEL]: IntroPanel,
[Config.panel_names.HOME_PANEL]: HomePanel,
[Config.panel_names.MY_PAGE_PANEL]: MyPagePanel,
[Config.panel_names.CATEGORY_PANEL]: CategoryPanel,
[Config.panel_names.SEARCH_PANEL]: SearchPanel,
/* VUI_DISABLE_START - VoicePanel panelMap 비활성화 */
// [Config.panel_names.VOICE_PANEL]: VoicePanel,
/* VUI_DISABLE_END */
[Config.panel_names.ON_SALE_PANEL]: OnSalePanel,
[Config.panel_names.TRENDING_NOW_PANEL]: TrendingNowPanel,
[Config.panel_names.HOT_PICKS_PANEL]: HotPicksPanel,
[Config.panel_names.FEATURED_BRANDS_PANEL]: FeaturedBrandsPanel,
[Config.panel_names.CART_PANEL]: CartPanel,
[Config.panel_names.ERROR_PANEL]: ErrorPanel,
[Config.panel_names.DEBUG_PANEL]: DebugPanel,
[Config.panel_names.DETAIL_PANEL]: DetailPanel,
[Config.panel_names.PLAYER_PANEL]: PlayerPanel,
[Config.panel_names.MEDIA_PANEL]: MediaPanel,
[Config.panel_names.CHECKOUT_PANEL]: CheckOutPanel,
[Config.panel_names.WELCOME_EVENT_PANEL]: WelcomeEventPanel,
[Config.panel_names.THEME_CURATION_PANEL]: ThemeCurationPanel,
[Config.panel_names.IMAGE_PANEL]: ImagePanel,
[Config.panel_names.CONFIRM_PANEL]: ConfirmPanel,
[Config.panel_names.USER_REVIEW_PANEL]: UserReviewPanel,
[Config.panel_names.JUST_FOR_YOU_PANEL]: JustForYouPanel,
[Config.panel_names.JUST_FOR_YOU_TEST_PANEL]: JustForYouTestPanel,
// [Config.panel_names.OPTIONAL_TERMS_PANEL]: TermsOfOptional,
};
const logTpNoLiveSet = new Set([
Config.LOG_TP_NO.LIVE.HOME,
Config.LOG_TP_NO.LIVE.FEATURED_BRANDS,
Config.LOG_TP_NO.LIVE.FULL,
Config.LOG_TP_NO.LIVE.ITEM_DETAIL,
]);
const STRING_CONF = {
YES: 'YES',
NO: 'NO',
EXIT: 'EXIT',
THIS_IS_AN_UNSUPPORTED_COUNTRY: 'This is an unsupported country.',
CHANGE_COUNTRY:
'If you have changed your LG service country setting, the usage information in Shop Time during your previous country setting will be deleted. Do you want to proceed?',
};
export default function MainView({ className, initService }) {
const dispatch = useDispatch();
const httpHeader = useSelector((state) => state.common.httpHeader);
const mainIndex = useSelector((state) => state.appData.mainIndex);
const panels = useSelector((state) => state.panels.panels);
const lastPanelAction = useSelector((state) => state.panels.lastPanelAction);
const loadingComplete = useSelector((state) => state.common?.loadingComplete);
const menuData = useSelector((state) => state.home.menuData?.data);
const {
popupVisible,
activePopup,
data: errorCode,
data: popupData,
} = useSelector((state) => state.common.popup);
const { showLoadingPanel, toast, toastText, isLoading, webOSVersion, deviceId } = useSelector(
(state) => state.common.appStatus
);
const homeInfo = useSelector((state) => state.home.homeInfo);
const skipEndOfServicePopup = useSelector((state) => state.localSettings.skipEndOfServicePopup);
const isInternetConnected = useSelector((state) => state.common.appStatus.isInternetConnected);
const deviceCountryCode = httpHeader?.['X-Device-Country'] || '';
const isLogSentRef = useRef(false);
const watchRecord = useSelector((state) => state.localSettings?.watchRecord);
const watchRecordRef = usePrevious(watchRecord);
const [tabActivated, setTabActivated] = useState(false);
const [imagePreloaded, setImagePreloaded] = useState(false);
const [ariaHidden, setAriaHidden] = useState(false);
const [showEndOfServicePopup, setShowEndOfServicePopup] = useState(false);
const topPanel = panels[panels.length - 1];
// BUYNOW_CONFIG 초기화 (마운트 시 한 번만 실행)
useEffect(() => {
// TV 배포용: Mock Mode 하드코딩 활성화
// 모든 상품에서 BUY NOW 버튼이 표시됨
const mockMode = false;
// 모듈 변수에 저장 (이후 ProductAllSection 등에서 메모리에서만 읽음)
BUYNOW_CONFIG.init(mockMode);
}, []);
// useEffect(() => {
// console.log('🔍 MainView 팝업 상태 변경:', {
// popupVisible,
// activePopup,
// });
// }, [popupVisible, activePopup]);
const isHomeOnTop = useMemo(() => {
return !mainIndex && (panels.length <= 0 || (panels.length === 1 && panels[0].panelInfo.modal));
}, [mainIndex, panels]);
const hasDetailPanel = useMemo(
() => panels.some((panel) => panel?.name === Config.panel_names.DETAIL_PANEL),
[panels]
);
const onPreImageLoadComplete = useCallback(() => {
// console.log('MainView onPreImageLoadComplete');
dispatch(changeAppStatus({ showLoadingPanel: { show: false } }));
setImagePreloaded(true);
}, [dispatch]);
const currentTabLayoutPanelInfo = useMemo(() => {
return panels[panels.length - 1]?.panelInfo;
}, [panels]);
const renderTopPanel = useCallback(() => {
if (panels && panels.length > 0) {
let renderingPanels = [];
const topPanel = panels[panels.length - 1];
const hasFeaturedBrandsPanel = panels.some(
(panel) => panel?.name === Config.panel_names.FEATURED_BRANDS_PANEL
);
const hasTrendingNowPanel = panels.some(
(panel) => panel?.name === Config.panel_names.TRENDING_NOW_PANEL
);
// 단독 패널 체크 - CheckOutPanel, CartPanel 등 단독으로 렌더링되어야 하는 패널들
if (DEBUG_MODE) {
console.log(`[PANEL_MainView] 🔍 Top panel name: ${topPanel?.name}`);
console.log(
`[PANEL_MainView] 🔍 isStandalonePanel check:`,
isStandalonePanel(topPanel?.name)
);
console.log(`[PANEL_MainView] 🔍 STANDALONE_PANELS:`, STANDALONE_PANELS);
console.log(
`[PANEL_MainView] 🔍 All panels:`,
panels.map((p) => ({ name: p.name, hasModal: !!p.panelInfo?.modal }))
);
}
if (isStandalonePanel(topPanel?.name)) {
if (DEBUG_MODE) {
console.log(
`[MainView] ✅ Standalone panel detected: ${topPanel?.name} - rendering independently`
);
}
renderingPanels = [topPanel]; // 단독 패널만 단독으로 렌더링
}
// 기존 3-layer 구조 체크: PlayerPanel + DetailPanel + MediaPanel(modal)
else {
const hasThreeLayerStructure =
panels.length >= 3 &&
// PlayerPanel이 맨 아래
(panels[panels.length - 3]?.name === Config.panel_names.PLAYER_PANEL ||
panels[panels.length - 3]?.name === Config.panel_names.PLAYER_PANEL_NEW) &&
// DetailPanel이 중간
panels[panels.length - 2]?.name === Config.panel_names.DETAIL_PANEL &&
// MediaPanel modal이 맨 위
panels[panels.length - 1]?.name === Config.panel_names.MEDIA_PANEL &&
panels[panels.length - 1]?.panelInfo?.modal === true;
if (hasThreeLayerStructure) {
if (DEBUG_MODE) {
console.log(
'[MainView] Rendering 3-layer structure: PlayerPanel + DetailPanel + MediaPanel'
);
}
if (hasFeaturedBrandsPanel || hasTrendingNowPanel) {
renderingPanels = panels.slice(-4);
} else {
renderingPanels = panels.slice(-3);
}
} else if (
panels[panels.length - 1]?.name === Config.panel_names.PLAYER_PANEL ||
panels[panels.length - 1]?.name === Config.panel_names.PLAYER_PANEL_NEW ||
panels[panels.length - 1]?.name === Config.panel_names.MEDIA_PANEL ||
panels[panels.length - 2]?.name === Config.panel_names.PLAYER_PANEL ||
panels[panels.length - 2]?.name === Config.panel_names.MEDIA_PANEL
) {
if (hasFeaturedBrandsPanel || hasTrendingNowPanel) {
renderingPanels = panels.slice(-3);
} else {
renderingPanels = panels.slice(-2);
}
} else {
renderingPanels = panels.slice(-1);
}
}
// DetailPanel 위치 확인 (있으면 항상 onTop 처리)
const detailPanelIndex = renderingPanels.findIndex(
(panel) => panel.name === Config.panel_names.DETAIL_PANEL
);
return (
<>
{(isHomeOnTop ||
hasDetailPanel ||
(panels.length === 1 &&
(panels[0]?.name === Config.panel_names.PLAYER_PANEL ||
panels[0]?.name === Config.panel_names.PLAYER_PANEL_NEW ||
panels[0]?.name === Config.panel_names.MEDIA_PANEL))) && (
{popupData && getErrorMessage( popupData.errorCode, popupData.errorMsg, popupData.retDetailCode, popupData.returnBindStrings )}
{' '}{contentTarget}
v1101-001