/*
 * Runtime Web – Unified Serverless Framework for Full-Stack TypeScript Applications
 * Documentation: https://runtimeweb.com/docs/getting-started
 *
 * @template: ai-chat
 */

/**
 * ErrorBoundary Component
 *
 * React error boundary for catching and displaying uncaught errors.
 */

import * as React from 'react';
import { Component, ErrorInfo, ReactNode } from 'react';

/**
 * ErrorBoundary props interface.
 */
interface ErrorBoundaryProps {
    /** Child components to render */
    children: ReactNode;
    /** Optional custom fallback UI */
    fallback?: ReactNode;
}

/**
 * ErrorBoundary state interface.
 */
interface ErrorBoundaryState {
    /** Whether an error has been caught */
    hasError: boolean;
    /** The caught error, if any */
    error: Error | null;
}

/**
 * ErrorBoundary component.
 *
 * Catches JavaScript errors anywhere in the child component tree,
 * logs those errors, and displays a fallback UI.
 *
 * @example
 * ```tsx
 * <ErrorBoundary>
 *   <App />
 * </ErrorBoundary>
 * ```
 */
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
    state: ErrorBoundaryState = {
        hasError: false,
        error: null,
    };

    /**
     * Update state when an error is caught.
     */
    static getDerivedStateFromError(error: Error): ErrorBoundaryState {
        return {
            hasError: true,
            error,
        };
    }

    /**
     * Log error information for debugging.
     */
    componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
        console.error('ErrorBoundary caught an error:', error);
        console.error('Error info:', errorInfo.componentStack);
    }

    /**
     * Reset error state to allow retry.
     */
    handleReset = (): void => {
        this.setState({
            hasError: false,
            error: null,
        });
    };

    render(): ReactNode {
        if (this.state.hasError) {
            // Render custom fallback if provided
            if (this.props.fallback) {
                return this.props.fallback;
            }

            // Default fallback UI
            return (
                <div className="error-boundary-fallback">
                    <div className="error-boundary-fallback__content">
                        <h2 className="error-boundary-fallback__title">
                            Something went wrong
                        </h2>
                        <p className="error-boundary-fallback__message">
                            An unexpected error occurred. Please try again.
                        </p>
                        <button
                            className="error-boundary-fallback__button"
                            onClick={this.handleReset}
                        >
                            Try again
                        </button>
                    </div>
                    <style>{`
                        .error-boundary-fallback {
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            min-height: 100vh;
                            padding: 2rem;
                            background-color: #f5f5f5;
                            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
                        }
                        .error-boundary-fallback__content {
                            text-align: center;
                            max-width: 400px;
                        }
                        .error-boundary-fallback__title {
                            margin: 0 0 1rem 0;
                            font-size: 1.5rem;
                            color: #333;
                        }
                        .error-boundary-fallback__message {
                            margin: 0 0 1.5rem 0;
                            color: #666;
                        }
                        .error-boundary-fallback__button {
                            padding: 0.75rem 1.5rem;
                            background-color: #007bff;
                            color: white;
                            border: none;
                            border-radius: 0.5rem;
                            font-size: 1rem;
                            cursor: pointer;
                            transition: background-color 0.2s;
                        }
                        .error-boundary-fallback__button:hover {
                            background-color: #0056b3;
                        }
                        @media (prefers-color-scheme: dark) {
                            .error-boundary-fallback {
                                background-color: #1a1a1a;
                            }
                            .error-boundary-fallback__title {
                                color: #e0e0e0;
                            }
                            .error-boundary-fallback__message {
                                color: #999;
                            }
                        }
                    `}</style>
                </div>
            );
        }

        return this.props.children;
    }
}
