/**
 * @ai-summary Error boundary to suppress harmless Google Maps DOM conflicts
 */

import { Component, ErrorInfo, ReactNode } from 'react';
import { Box, Alert } from '@mui/material';

interface Props {
  children: ReactNode;
  fallback?: ReactNode;
}

interface State {
  hasError: boolean;
  error: Error | null;
}

/**
 * Error boundary that catches and suppresses DOM manipulation errors
 * from Google Maps conflicting with React reconciliation.
 *
 * Known issues:
 * - Google Maps directly manipulates DOM nodes
 * - React tries to remove nodes Google Maps already moved/removed
 * - Causes: "Failed to execute 'removeChild' on 'Node'"
 *
 * This is harmless - the map still works, but React reconciliation fails.
 */
export class GoogleMapsErrorBoundary extends Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = { hasError: false, error: null };
  }

  static getDerivedStateFromError(error: Error): State {
    // Check if this is a harmless Google Maps DOM conflict
    const isGoogleMapsDomError =
      error.message?.includes('removeChild') ||
      error.message?.includes('insertBefore') ||
      error.message?.includes('replaceChild') ||
      error.message?.includes('The node to be removed is not a child') ||
      error.name === 'NotFoundError' ||
      error instanceof DOMException;

    if (isGoogleMapsDomError) {
      console.debug('[GoogleMapsErrorBoundary] Suppressed harmless DOM error:', error.message);
      // Suppress the error - don't show error state, but force recovery
      return { hasError: false, error: null };
    }

    // For other errors, show error state
    return { hasError: true, error };
  }

  override componentDidCatch(error: Error, errorInfo: ErrorInfo) {
    // Log non-Google Maps errors
    const isGoogleMapsDomError =
      error.message?.includes('removeChild') ||
      error.message?.includes('insertBefore') ||
      error.message?.includes('replaceChild') ||
      error.message?.includes('The node to be removed is not a child') ||
      error.name === 'NotFoundError' ||
      error instanceof DOMException;

    if (isGoogleMapsDomError) {
      // Suppress completely - not even debug logs
      event?.preventDefault?.();
      event?.stopPropagation?.();
    } else {
      console.error('[GoogleMapsErrorBoundary] Caught error:', error, errorInfo);
    }
  }

  override render() {
    if (this.state.hasError && this.state.error) {
      // Show fallback UI for real errors
      return (
        this.props.fallback || (
          <Box
            sx={{
              padding: 2,
              display: 'flex',
              alignItems: 'center',
              justifyContent: 'center',
              minHeight: '300px'
            }}
          >
            <Alert severity="error">
              Map failed to load: {this.state.error.message}
            </Alert>
          </Box>
        )
      );
    }

    return this.props.children;
  }
}

export default GoogleMapsErrorBoundary;
