import React, { Component } from 'react';
import { __ } from '@wordpress/i18n';

class ErrorBoundary extends Component {
  constructor(props) {
    super(props);
    this.state = {
      hasError: false,
      error: null,
      errorInfo: null,
      isRecovering: false,
    };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  isRecoverableChunkError(error) {
    const message = error?.message || error?.toString?.() || '';

    return [
      'Failed to fetch dynamically imported module',
      'Importing a module script failed',
      'ChunkLoadError',
      'Loading chunk',
    ].some((needle) => message.includes(needle));
  }

  tryRecoverFromChunkError() {
    if (typeof window === 'undefined' || typeof sessionStorage === 'undefined') {
      return false;
    }

    const recoveryUrl = new URL(window.location.href);
    const retryKey = `prorank:chunk-reload:${recoveryUrl.pathname}${recoveryUrl.search}${recoveryUrl.hash}`;

    if (sessionStorage.getItem(retryKey)) {
      return false;
    }

    sessionStorage.setItem(retryKey, '1');
    recoveryUrl.searchParams.set('prorank_chunk_retry', Date.now().toString());
    this.setState({ isRecovering: true });
    window.location.replace(recoveryUrl.toString());
    return true;
  }

  componentDidCatch(error, errorInfo) {
    this.setState({
      error,
      errorInfo,
    });

    if (this.isRecoverableChunkError(error)) {
      this.tryRecoverFromChunkError();
    }
  }

  render() {
    if (this.state.hasError) {
      if (this.state.isRecovering) {
        return (
          <div
            style={{
              padding: '20px',
              background: '#eff6ff',
              border: '1px solid #bfdbfe',
              borderRadius: '4px',
              margin: '20px',
            }}
          >
            <h2>{__('Refreshing admin page…', 'prorank-seo')}</h2>
            <p>{__('A newer ProRank admin bundle was detected. Reloading this page once to recover.', 'prorank-seo')}</p>
          </div>
        );
      }

      return (
        <div
          style={{
            padding: '20px',
            background: '#fee',
            border: '1px solid #fcc',
            borderRadius: '4px',
            margin: '20px',
          }}
        >
          <h2>{__('Something went wrong', 'prorank-seo')}</h2>
          <p>{__('If this happened after a plugin update, reload the page to fetch the current admin bundle.', 'prorank-seo')}</p>
          <button
            type="button"
            onClick={() => window.location.reload()}
            style={{
              marginTop: '10px',
              padding: '8px 12px',
              background: '#2271b1',
              color: '#fff',
              border: '0',
              borderRadius: '4px',
              cursor: 'pointer',
            }}
          >
            {__('Reload Page', 'prorank-seo')}
          </button>
          <details style={{ whiteSpace: 'pre-wrap', marginTop: '10px' }}>
            <summary>{__('Error details', 'prorank-seo')}</summary>
            {this.state.error !== null && this.state.error.toString()}
            <br />
            {this.state.errorInfo !== null && this.state.errorInfo.componentStack}
          </details>
        </div>
      );
    }

    return this.props.children;
  }
}

export default ErrorBoundary;
