import { Component, type ReactNode } from 'react';

interface Props {
  children: ReactNode;
}

interface State {
  hasError: boolean;
  isChunkError: boolean;
}

/**
 * Global error boundary that catches React rendering crashes.
 * Detects stale chunk errors (after redeployment) and offers auto-reload.
 */
export default class ErrorBoundary extends Component<Props, State> {
  state: State = { hasError: false, isChunkError: false };

  static getDerivedStateFromError(error: Error): State {
    const isChunkError = isChunkLoadError(error);
    return { hasError: true, isChunkError };
  }

  componentDidCatch(error: Error) {
    // If it's a stale chunk error, auto-reload once (avoid infinite loop via sessionStorage flag)
    if (isChunkLoadError(error)) {
      const reloadKey = 'cm_chunk_reload';
      const lastReload = sessionStorage.getItem(reloadKey);
      const now = Date.now();
      // Only auto-reload if we haven't done so in the last 10 seconds
      if (!lastReload || now - parseInt(lastReload, 10) > 10000) {
        sessionStorage.setItem(reloadKey, String(now));
        window.location.reload();
        return;
      }
    }
  }

  handleReload = () => {
    window.location.reload();
  };

  render() {
    if (this.state.hasError) {
      return (
        <div
          style={{
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            justifyContent: 'center',
            height: '100vh',
            background: '#1a1025',
            color: '#e0e0e0',
            fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
            textAlign: 'center',
            padding: '0 24px',
          }}
        >
          <div style={{ fontSize: 48, marginBottom: 16 }}>
            {this.state.isChunkError ? '\u21BB' : '\u26A0'}
          </div>
          <h2 style={{ margin: '0 0 8px', fontSize: 20, fontWeight: 600 }}>
            {this.state.isChunkError
              ? 'Application Updated'
              : 'Something went wrong'}
          </h2>
          <p style={{ margin: '0 0 24px', color: '#999', maxWidth: 400, lineHeight: 1.5 }}>
            {this.state.isChunkError
              ? 'A new version has been deployed. Please refresh to load the latest version.'
              : 'An unexpected error occurred. A page refresh usually fixes this.'}
          </p>
          <button
            onClick={this.handleReload}
            style={{
              padding: '10px 24px',
              fontSize: 14,
              fontWeight: 500,
              border: 'none',
              borderRadius: 6,
              background: '#9d4edd',
              color: '#fff',
              cursor: 'pointer',
              transition: 'opacity 0.2s',
            }}
            onMouseOver={(e) => (e.currentTarget.style.opacity = '0.85')}
            onMouseOut={(e) => (e.currentTarget.style.opacity = '1')}
          >
            Refresh Page
          </button>
        </div>
      );
    }

    return this.props.children;
  }
}

/** Detect chunk/module load errors (stale deployments) */
function isChunkLoadError(error: Error): boolean {
  const msg = error.message || '';
  return (
    msg.includes('Failed to fetch dynamically imported module') ||
    msg.includes('Loading chunk') ||
    msg.includes('Loading CSS chunk') ||
    msg.includes('error loading dynamically imported module') ||
    msg.includes('Importing a module script failed') ||
    // Vite-specific: chunk not found
    msg.includes('is not a valid JavaScript MIME type') ||
    // Generic syntax errors from loading wrong content (e.g., HTML 404 page as JS)
    (error.name === 'SyntaxError' && msg.includes('Unexpected token'))
  );
}
