/**
 * Error Boundary Component for Ink/React
 *
 * Catches JavaScript errors in child components and displays
 * a fallback UI instead of crashing the entire CLI.
 *
 * Based on React error boundary pattern adapted for terminal UI.
 */
import React, { Component } from 'react';
import { Box, Text } from 'ink';
import { logger } from '../../utils/logger.js';
/**
 * Error Boundary for Ink components
 * Prevents the entire CLI from crashing on component errors
 */
export class ErrorBoundary extends Component {
    constructor(props) {
        super(props);
        this.state = {
            hasError: false,
            error: null,
            errorInfo: null,
        };
    }
    static getDerivedStateFromError(error) {
        return { hasError: true, error };
    }
    componentDidCatch(error, errorInfo) {
        this.setState({ errorInfo });
        // Call custom error handler if provided
        if (this.props.onError) {
            this.props.onError(error, errorInfo);
        }
        // Log to console for debugging
        logger.error('ErrorBoundary caught an error', error, {
            componentStack: errorInfo.componentStack
        });
    }
    render() {
        if (this.state.hasError) {
            // Custom fallback UI
            if (this.props.fallback) {
                return this.props.fallback;
            }
            // Default error UI
            return (React.createElement(Box, { flexDirection: "column", padding: 1, borderStyle: "round", borderColor: "red" },
                React.createElement(Box, { marginBottom: 1 },
                    React.createElement(Text, { color: "red", bold: true }, "Something went wrong")),
                React.createElement(Box, { marginBottom: 1 },
                    React.createElement(Text, { color: "yellow" }, this.state.error?.message || 'An unexpected error occurred')),
                this.props.showDetails && this.state.error && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
                    React.createElement(Text, { color: "gray", dimColor: true },
                        "Error: ",
                        this.state.error.name),
                    this.state.errorInfo?.componentStack && (React.createElement(Text, { color: "gray", dimColor: true }, this.state.errorInfo.componentStack.slice(0, 500))))),
                React.createElement(Box, { marginTop: 1 },
                    React.createElement(Text, { color: "gray" }, "Press Ctrl+C to exit or try again."))));
        }
        return this.props.children;
    }
}
export function withErrorBoundary(WrappedComponent, options = {}) {
    const WithErrorBoundaryComponent = (props) => (React.createElement(ErrorBoundary, { fallback: options.fallback, onError: options.onError, showDetails: options.showDetails },
        React.createElement(WrappedComponent, { ...props })));
    WithErrorBoundaryComponent.displayName = `WithErrorBoundary(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
    return WithErrorBoundaryComponent;
}
/**
 * Specialized error boundary for streaming content
 */
export class StreamingErrorBoundary extends Component {
    constructor(props) {
        super(props);
        this.state = {
            hasError: false,
            error: null,
            errorInfo: null,
            retries: 0,
        };
    }
    static getDerivedStateFromError(error) {
        return { hasError: true, error };
    }
    componentDidCatch(error, errorInfo) {
        this.setState({ errorInfo });
        if (this.props.onError) {
            this.props.onError(error, errorInfo);
        }
    }
    handleRetry = () => {
        const maxRetries = this.props.retryCount || 3;
        if (this.state.retries < maxRetries) {
            this.setState((prev) => ({
                hasError: false,
                error: null,
                errorInfo: null,
                retries: prev.retries + 1,
            }));
        }
    };
    render() {
        if (this.state.hasError) {
            const maxRetries = this.props.retryCount || 3;
            const canRetry = this.state.retries < maxRetries;
            return (React.createElement(Box, { flexDirection: "column", padding: 1 },
                React.createElement(Text, { color: "yellow" },
                    "Streaming error: ",
                    this.state.error?.message || 'Unknown error'),
                canRetry && (React.createElement(Text, { color: "gray", dimColor: true },
                    "Retry ",
                    this.state.retries + 1,
                    "/",
                    maxRetries,
                    "..."))));
        }
        return this.props.children;
    }
}
export default ErrorBoundary;
//# sourceMappingURL=ErrorBoundary.js.map