import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
 * @license
 * Copyright 2025 Vybestack LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { Component } from 'react';
import { Box, Text } from 'ink';
/**
 * Enhanced error boundary that detects and reports React errors,
 * including "Maximum update depth exceeded" errors.
 */
export class ErrorBoundary extends Component {
    errorTimestamps = [];
    ERROR_TIME_WINDOW = 5000; // 5 seconds
    MAX_ERRORS_IN_WINDOW = 5;
    constructor(props) {
        super(props);
        this.state = {
            hasError: false,
            error: null,
            errorInfo: null,
            errorCount: 0,
        };
    }
    static getDerivedStateFromError(error) {
        return {
            hasError: true,
            error,
        };
    }
    componentDidCatch(error, errorInfo) {
        const now = Date.now();
        this.errorTimestamps.push(now);
        // Clean up old timestamps
        this.errorTimestamps = this.errorTimestamps.filter((timestamp) => timestamp > now - this.ERROR_TIME_WINDOW);
        // Check if we're in an error loop
        const isErrorLoop = this.errorTimestamps.length > this.MAX_ERRORS_IN_WINDOW;
        // Special handling for Maximum update depth exceeded
        const isMaxUpdateDepthError = error.message.includes('Maximum update depth exceeded');
        if (isMaxUpdateDepthError || isErrorLoop) {
            console.error('CRITICAL: Render loop detected!');
            console.error('Error:', error.message);
            console.error('Component Stack:', errorInfo.componentStack);
            if (isMaxUpdateDepthError) {
                console.error('\nThis error typically occurs when:');
                console.error('1. setState is called inside render()');
                console.error('2. useEffect has missing or incorrect dependencies');
                console.error('3. Props are recreated on every render (objects, arrays, functions)');
                console.error('\nCheck recent changes to hooks and state updates.');
            }
        }
        // Log error details
        console.error('React Error Boundary caught an error:', error);
        console.error('Error Info:', errorInfo);
        console.error('Error count in window:', this.errorTimestamps.length);
        // Call custom error handler if provided
        if (this.props.onError) {
            this.props.onError(error, errorInfo);
        }
        // Update state with error info
        this.setState((prevState) => ({
            errorInfo,
            errorCount: prevState.errorCount + 1,
        }));
        // If we're in an error loop, try to break out
        if (isErrorLoop) {
            // Force a hard refresh after a delay to break the loop
            setTimeout(() => {
                console.error('Attempting to recover from error loop...');
                this.setState({
                    hasError: false,
                    error: null,
                    errorInfo: null,
                    errorCount: 0,
                });
                this.errorTimestamps = [];
            }, 1000);
        }
    }
    render() {
        if (this.state.hasError && this.state.error) {
            // Use custom fallback if provided
            if (this.props.fallback && this.state.errorInfo) {
                return this.props.fallback(this.state.error, this.state.errorInfo);
            }
            // Default error UI
            const isMaxUpdateDepthError = this.state.error.message.includes('Maximum update depth exceeded');
            return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { color: "red", bold: true, children: isMaxUpdateDepthError
                            ? 'CRITICAL: Render Loop Error'
                            : '❌ An error occurred' }), _jsx(Text, { color: "red", children: this.state.error.message }), this.state.errorCount > 1 && (_jsxs(Text, { color: "yellow", children: ["Error count: ", this.state.errorCount] })), isMaxUpdateDepthError && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "yellow", children: "This error indicates an infinite render loop." }), _jsx(Text, { color: "yellow", children: "Common causes:" }), _jsx(Text, { color: "yellow", children: "\u2022 State updates during render" }), _jsx(Text, { color: "yellow", children: "\u2022 Incorrect useEffect dependencies" }), _jsx(Text, { color: "yellow", children: "\u2022 Non-memoized props causing re-renders" })] })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Check the console for more details." }) })] }));
        }
        return this.props.children;
    }
}
/**
 * Hook to wrap a component with an error boundary.
 *
 * @example
 * ```typescript
 * function MyApp() {
 *   return (
 *     <ErrorBoundary onError={(error, info) => logError(error, info)}>
 *       <App />
 *     </ErrorBoundary>
 *   );
 * }
 * ```
 */
export function withErrorBoundary(Component, errorBoundaryProps) {
    const WrappedComponent = (props) => (_jsx(ErrorBoundary, { ...errorBoundaryProps, children: _jsx(Component, { ...props }) }));
    WrappedComponent.displayName = `withErrorBoundary(${Component.displayName || Component.name})`;
    return WrappedComponent;
}
//# sourceMappingURL=ErrorBoundary.js.map