
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
import "./index.css";
import { AuthProvider } from './hooks/useAuth';
import { ModalManagerProvider } from './contexts/ModalManagerContext';
import { taskScheduler } from './lib/task-scheduler';
import { initPreloading } from './utils/preloadCritical';
import { guardConsole } from './utils/consoleGuard';
import { track } from './lib/analytics';

// Mobile viewport height fix
function setViewportHeight() {
  const vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
}

guardConsole();

// Set on load and resize with throttling for performance
let resizeTimeout: number;
const throttledSetViewportHeight = () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = window.setTimeout(setViewportHeight, 100);
};

// Initialize viewport height and listeners
setViewportHeight();
window.addEventListener('resize', throttledSetViewportHeight, { passive: true });
window.addEventListener('orientationchange', () => {
  setTimeout(setViewportHeight, 150);
}, { passive: true });

// Optimized global tracking function declarations
declare global {
  interface Window {
    trackButtonClick: (buttonText: string, buttonLocation: string, buttonType: string) => void;
    trackFormSubmission: (formName: string, formLocation: string) => void;
    trackPageView: (pagePath: string, pageTitle: string) => void;
    trackFormFieldInteraction: (fieldName: string, fieldLength: number, fieldStatus: string) => void;
    dataLayer: any[];
    cgTrack?: (eventName: string, properties?: Record<string, unknown>) => void;
    __cgTrackQueue?: Array<{ eventName: string; properties?: Record<string, unknown> }>;
    __cgAnalytics?: Record<string, unknown>;
  }
}

// Main: Starting ConnectGym app

const flushAnalyticsQueue = () => {
  if (!window.__cgTrackQueue?.length) return;
  const queued = window.__cgTrackQueue.splice(0, window.__cgTrackQueue.length);
  queued.forEach(({ eventName, properties }) => {
    track(eventName, properties);
  });
};

window.cgTrack = (eventName, properties) => {
  track(eventName, properties);
};

flushAnalyticsQueue();

const rootElement = document.getElementById("root");
if (!rootElement) {
  throw new Error("Root element not found");
}

// Optimized React root creation with yielding
const root = createRoot(rootElement);

// Schedule React render to prevent blocking
taskScheduler.schedule(() => {
  root.render(
    <StrictMode>
      <AuthProvider>
        <ModalManagerProvider>
          <App />
        </ModalManagerProvider>
      </AuthProvider>
    </StrictMode>
  );
}, 'high');

// Optimized loader removal with yielding
const removeInitialLoader = () => {
  taskScheduler.schedule(() => {
    const loader = document.getElementById('initial-loader');
    if (loader) {
      loader.style.opacity = '0';
      loader.style.transition = 'opacity 0.3s ease-out';
      
      // Use scheduler for cleanup
      taskScheduler.schedule(() => {
        loader.remove();
      }, 'low');
    }
  }, 'normal');
};

// Remove loader with yielding
removeInitialLoader();

// Main: React app rendered

// Optimized non-critical feature initialization with task scheduling
function initializeNonCriticalFeatures() {
  // Break up initialization into smaller tasks to prevent FID issues
  const initTasks = [
    (): Promise<any> => import('@/lib/web-vitals').then((m): any => m?.initWebVitals?.()).catch((): any => null),
    (): Promise<any> => import('virtual:pwa-register').then((m): void => {
      if (m?.registerSW) {
        const updateSW = m.registerSW({
          immediate: false,
          onNeedRefresh(): void {
            // Non-blocking update prompt
            taskScheduler.scheduleIdle((): void => {
              if (confirm('새로운 업데이트가 있습니다. 지금 업데이트하시겠습니까?')) {
                updateSW(true);
              }
            });
          },
        });
      }
    }).catch((): any => null),
    (): Promise<any> => import('@/lib/sentry').then((m): any => m?.initSentry?.()).catch((): any => null),
  ];

  // Schedule each initialization task separately to prevent blocking
  initTasks.forEach((task) => {
    taskScheduler.schedule(task, 'low');
  });
}

// Use scheduler to defer initialization
taskScheduler.scheduleIdle(initializeNonCriticalFeatures);

// Initialize critical resource preloading
initPreloading();

// Initialize mobile optimizations
taskScheduler.scheduleIdle((): void => {
  import('@/utils/mobileOptimization').then(({ initializeMobileOptimizations }): void => {
    initializeMobileOptimizations();
  }).catch((): any => null);
});
