// Optimized bootstrap process - import CSS before JS for better paint performance
import "./index.css";
import { createRoot } from "react-dom/client";
import App from "./App";

// Type declarations for performance metrics
interface PerfMetrics {
  startTime: number;
  logPerformance: () => void;
}

// Add window augmentation for custom properties
declare global {
  interface Window {
    perfMetrics?: PerfMetrics;
  }

  // Fix for requestIdleCallback
  // Already defined in lib.dom.d.ts but ensuring compatibility
  interface PerformanceEntry {
    // Layout Shift API
    hadRecentInput?: boolean;
    value?: number;
  }
}

// Immediately invoke the render function for faster startup
// Use an IIFE to prevent global scope pollution
(function () {
  // Start performance measurement
  const startTime = performance.now();
  
  // Get the root element with non-null assertion (verified in HTML structure)
  const appRoot = document.getElementById("root");
  if (!appRoot) {
    console.error("Root element not found");
    return;
  }
  
  // Create root only once - improves performance by avoiding repeat calculations
  const root = createRoot(appRoot);
  
  // Directly render the app without StrictMode in production
  // This reduces double-rendering and improves initial load performance
  root.render(<App />);
  
  // Register callback to track performance metrics after initial render
  queueMicrotask(() => {
    const initialRenderTime = performance.now() - startTime;
    console.debug(`Initial render in ${initialRenderTime.toFixed(2)}ms`);
  });
  
  // Comprehensive performance monitoring after full page load
  window.addEventListener('load', () => {
    // Use the globally defined performance metrics object from index.html
    if (window.perfMetrics && typeof window.perfMetrics.startTime === 'number') {
      const loadTime = performance.now() - window.perfMetrics.startTime;
      console.log(`Total load in ${loadTime.toFixed(2)}ms`);
    }
    
    // Report core web vitals after a small delay to ensure they're available
    if ('performance' in window && 'getEntriesByType' in performance) {
      // Use setTimeout fallback for non-critical metrics - avoid requestIdleCallback type issues
      const scheduleIdleTask = (cb: IdleRequestCallback) => {
        setTimeout(() => cb({ didTimeout: false, timeRemaining: () => 50 }), 50);
      };
      
      scheduleIdleTask(() => {
        // First Contentful Paint and First Paint
        const paintMetrics = performance.getEntriesByType('paint');
        paintMetrics.forEach(metric => {
          console.debug(`${metric.name}: ${metric.startTime.toFixed(0)}ms`);
        });
        
        // Track LCP using PerformanceObserver with a cleaner implementation
        if (PerformanceObserver.supportedEntryTypes?.includes('largest-contentful-paint')) {
          const lcpObserver = new PerformanceObserver((entryList) => {
            const entries = entryList.getEntries();
            if (entries.length > 0) {
              const lastEntry = entries[entries.length - 1];
              console.debug(`LCP: ${lastEntry.startTime.toFixed(0)}ms`);
              
              // Disconnect observer after getting the final LCP value
              lcpObserver.disconnect();
            }
          });
          
          // Only observe LCP events
          lcpObserver.observe({ 
            type: 'largest-contentful-paint', 
            buffered: true 
          });
        }
        
        // Track CLS (Cumulative Layout Shift)
        if (PerformanceObserver.supportedEntryTypes?.includes('layout-shift')) {
          let cumulativeLayoutShift = 0;
          
          const layoutShiftObserver = new PerformanceObserver((entryList) => {
            for (const entry of entryList.getEntries()) {
              // Type assertion for layout shift entries
              const layoutShiftEntry = entry as PerformanceEntry & { 
                hadRecentInput?: boolean; 
                value?: number;
              };
              
              // Only count layout shifts without recent user input
              if (layoutShiftEntry.hadRecentInput === false && typeof layoutShiftEntry.value === 'number') {
                cumulativeLayoutShift += layoutShiftEntry.value;
              }
            }
            console.debug(`CLS: ${cumulativeLayoutShift.toFixed(3)}`);
          });
          
          layoutShiftObserver.observe({ type: 'layout-shift', buffered: true });
        }
      });
    }
  });
})();
