import * as Sentry from "@sentry/react";

// Initialize Sentry as early as possible
Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  environment: import.meta.env.VITE_SENTRY_ENVIRONMENT || 'development',
  release: import.meta.env.VITE_SENTRY_RELEASE || '1.0.0',
  
  // Performance Monitoring
  tracesSampleRate: parseFloat(import.meta.env.VITE_SENTRY_TRACES_SAMPLE_RATE || '0.1'),
  
  // Session Replay
  replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
  replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
  
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.replayIntegration({
      // Mask all text content, record only clicks, inputs, and navigation
      maskAllText: true,
      blockAllMedia: true,
    }),
    Sentry.captureConsoleIntegration({ levels: ['error'] }),
  ],
  
  // Filter sensitive data before sending to Sentry
  beforeSend(event, _hint) {
    // Drop duplicate "[CLIENT ERROR] Upload failed with status …" shadow events
    // generated by captureConsoleIntegration for upload errors that are already
    // reported via Sentry.captureException in S3UploadService. The console-shadow
    // event has no real stack frames and pollutes issue grouping (see prod issue
    // REALTIME-INTERVIEW-APP-FRONT-6V — an untagged twin of the structured event).
    if (event.logger === 'console') {
      const consoleMsg =
        event.message ||
        event.exception?.values?.[0]?.value ||
        '';
      if (
        /\[CLIENT ERROR\]/.test(consoleMsg) &&
        /Upload failed with status \d+|S3 upload (failed|network error|aborted)/i.test(consoleMsg)
      ) {
        return null;
      }
    }

    // Remove sensitive data from error context
    if (event.extra) {
      delete event.extra.password;
      delete event.extra.token;
      delete event.extra.apiKey;
      delete event.extra.accessToken;
      delete event.extra.secret;
      delete event.extra.authorization;
    }
    
    // Filter sensitive request data
    if (event.request) {
      if (event.request.headers) {
        delete event.request.headers.authorization;
        delete event.request.headers.Authorization;
        delete event.request.headers['x-api-key'];
        delete event.request.headers['X-API-Key'];
      }
    }
    
    return event;
  },
  
  // Set default tags for all events
  initialScope: {
    tags: {
      component: 'browser-example',
      environment: import.meta.env.VITE_SENTRY_ENVIRONMENT || 'development'
    }
  }
});

import React from 'react'
import ReactDOM from 'react-dom/client'
import { App } from './App'
import ErrorBoundary from './components/ErrorBoundary';
import './index.css'
import { AuthProvider } from "react-oidc-context"
import awsConfig from './aws-exports'
import { enableAutoHealthCheck } from './utils/deploymentHealthCheck'
import { TooltipProvider } from './components/ui/tooltip'

const cognitoAuthConfig = {
  authority: `https://cognito-idp.${awsConfig.Auth.region}.amazonaws.com/${awsConfig.Auth.userPoolId}`,
  client_id: awsConfig.Auth.userPoolWebClientId,
  redirect_uri: awsConfig.Auth.oauth.redirectSignIn,
  response_type: "code",
  scope: awsConfig.Auth.oauth.scope.join(" "),
}

// Global error handler for chunk loading failures
window.addEventListener('error', (event) => {
  const error = event.error;
  const message = event.message || '';
  
  // Check if this is a chunk loading error
  if (
    message.includes('Loading chunk') ||
    message.includes('Failed to fetch dynamically imported module') ||
    (error && error.message && (
      error.message.includes('Loading chunk') ||
      error.message.includes('Failed to fetch dynamically imported module') ||
      error.message.includes('ChunkLoadError')
    ))
  ) {
    console.warn('🔄 Chunk loading failed, attempting recovery...', {
      message,
      error: error?.message,
      stack: error?.stack
    });
    
    // Clear all caches and reload to get fresh chunks
    if ('caches' in window) {
      caches.keys().then(names => {
        names.forEach(name => caches.delete(name));
      }).finally(() => {
        (window as any).location.reload();
      });
    } else {
      (window as any).location.reload();
    }
    
    // Prevent the error from propagating
    event.preventDefault();
    return true;
  }
});

// Handle unhandled promise rejections for import() failures
window.addEventListener('unhandledrejection', (event) => {
  const reason = event.reason;
  
  if (
    reason &&
    (reason.message?.includes('Failed to fetch dynamically imported module') ||
     reason.message?.includes('Loading chunk') ||
     reason.message?.includes('ChunkLoadError'))
  ) {
    console.warn('🔄 Dynamic import failed, attempting recovery...', reason);
    
    // Clear caches and reload
    if ('caches' in window) {
      caches.keys().then(names => {
        names.forEach(name => caches.delete(name));
      }).finally(() => {
        (window as any).location.reload();
      });
    } else {
      (window as any).location.reload();
    }
    
    // Prevent the unhandled rejection
    event.preventDefault();
  }
});

// Handle portal-related DOM errors that don't get caught by ErrorBoundary
window.addEventListener('error', (event) => {
  const error = event.error;
  const message = event.message || '';
  
  // Check if this is a portal-related DOM error
  if (
    message.includes('removeChild') ||
    message.includes('not a child of this node') ||
    (error && error.message && (
      error.message.includes('removeChild') ||
      error.message.includes('not a child of this node') ||
      error.message.includes('Failed to execute') && error.message.includes('Node')
    ))
  ) {
    console.warn('🔧 Portal DOM error detected, attempting aggressive recovery...', {
      message,
      error: error?.message,
      portalRoot: {
        exists: !!document.getElementById('radix-portal-root'),
        connected: document.getElementById('radix-portal-root')?.isConnected,
        children: document.getElementById('radix-portal-root')?.children.length
      }
    });
    
    // Don't attempt aggressive cleanup - it can interfere with React's reconciliation
    // Just log the state for debugging
    console.warn('🔧 Portal cleanup skipped to avoid React conflicts');
    
    // Log to Sentry with context but don't crash the app
    Sentry.withScope((scope) => {
      scope.setTag('errorType', 'portal-dom-error-global');
      scope.setLevel('warning');
      scope.setContext('portalState', {
        portalRootExists: !!document.getElementById('radix-portal-root'),
        portalRootConnected: document.getElementById('radix-portal-root')?.isConnected,
        portalRootChildren: document.getElementById('radix-portal-root')?.children.length,
        aggressiveCleanupAttempted: true
      });
      
      if (error) {
        Sentry.captureException(error);
      } else {
        Sentry.captureMessage(`Portal DOM error: ${message}`);
      }
    });
    
    // Prevent the error from causing a crash
    event.preventDefault();
    return true;
  }
});

// Enable deployment health checks in development
if (import.meta.env.DEV) {
  enableAutoHealthCheck();
}

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <AuthProvider {...cognitoAuthConfig}>
      <TooltipProvider delayDuration={300}>
        <ErrorBoundary>
          <App />
        </ErrorBoundary>
      </TooltipProvider>
    </AuthProvider>
  </React.StrictMode>,
)
