"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorBoundary = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
 * Error Boundary Component
 * Catches and handles React component errors gracefully
 */
const react_1 = require("react");
const react_2 = require("@chakra-ui/react");
class ErrorBoundary extends react_1.Component {
    constructor(props) {
        super(props);
        this.resetTimeoutId = null;
        this.previousResetKeys = [];
        this.reportError = async (error, errorInfo) => {
            try {
                await fetch(this.props.reportingEndpoint, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        message: error.message,
                        stack: error.stack,
                        componentStack: errorInfo.componentStack,
                        level: this.props.level,
                        timestamp: new Date().toISOString(),
                        userAgent: navigator.userAgent,
                        url: window.location.href,
                    }),
                });
            }
            catch (reportingError) {
                console.error('Failed to report error:', reportingError);
            }
        };
        this.handleReset = () => {
            this.setState({
                hasError: false,
                error: null,
                errorInfo: null,
            });
            // Call onReset callback if provided
            this.props.onReset?.();
            // Clear any pending reset timeout
            if (this.resetTimeoutId) {
                clearTimeout(this.resetTimeoutId);
                this.resetTimeoutId = null;
            }
        };
        this.state = {
            hasError: false,
            error: null,
            errorInfo: null,
        };
        if (props.resetKeys) {
            this.previousResetKeys = props.resetKeys;
        }
    }
    static getDerivedStateFromError(error) {
        return {
            hasError: true,
            error,
            errorInfo: null,
        };
    }
    componentDidUpdate(prevProps) {
        const { resetKeys, resetOnPropsChange } = this.props;
        const { hasError } = this.state;
        // Reset on resetKeys change
        if (hasError && prevProps.resetKeys !== resetKeys) {
            if (resetKeys?.some((key, idx) => key !== this.previousResetKeys[idx])) {
                this.handleReset();
                this.previousResetKeys = resetKeys;
            }
        }
        // Reset on any props change if enabled
        if (hasError && resetOnPropsChange && prevProps.children !== this.props.children) {
            this.handleReset();
        }
    }
    componentDidCatch(error, errorInfo) {
        this.setState({
            error,
            errorInfo,
        });
        // Call onError callback if provided
        this.props.onError?.(error, errorInfo);
        // Log error to monitoring service
        const errorLevel = this.props.level || 'component';
        console.error(`[ErrorBoundary:${errorLevel}] Error caught:`, error, errorInfo);
        // Report error if enabled
        if (this.props.enableReporting && this.props.reportingEndpoint) {
            this.reportError(error, errorInfo);
        }
    }
    componentWillUnmount() {
        // Clean up any pending timeouts
        if (this.resetTimeoutId) {
            clearTimeout(this.resetTimeoutId);
        }
    }
    render() {
        if (this.state.hasError) {
            // Use custom fallback if provided
            if (this.props.fallback) {
                if (typeof this.props.fallback === 'function') {
                    return this.props.fallback({ error: this.state.error });
                }
                return this.props.fallback;
            }
            const showDetails = this.props.showDetails ?? process.env.NODE_ENV === 'development';
            const errorMessage = this.props.customErrorMessage || this.state.error?.message || 'An unexpected error occurred';
            // Default error UI with enhanced accessibility
            return ((0, jsx_runtime_1.jsx)(react_2.Box, { p: 6, borderWidth: "1px", borderRadius: "lg", bg: "surface-bg", boxShadow: "elevation-low", role: "alert", "aria-live": "assertive", "aria-atomic": "true", children: (0, jsx_runtime_1.jsxs)(react_2.VStack, { spacing: 4, align: "stretch", children: [(0, jsx_runtime_1.jsx)(react_2.Heading, { size: "md", color: "status-error", id: "error-boundary-heading", children: "Something went wrong" }), (0, jsx_runtime_1.jsx)(react_2.Text, { color: "text-body", "aria-describedby": "error-boundary-heading", children: errorMessage }), showDetails && this.state.errorInfo && ((0, jsx_runtime_1.jsxs)(react_2.Box, { p: 4, bg: "surface-raised", borderRadius: "md", fontSize: "sm", fontFamily: "mono", whiteSpace: "pre-wrap", overflowX: "auto", "aria-label": "Error details", tabIndex: 0, children: [(0, jsx_runtime_1.jsx)(react_2.Text, { color: "text-secondary", fontWeight: "medium", mb: 2, children: "Component Stack:" }), (0, jsx_runtime_1.jsx)(react_2.Text, { color: "text-muted", fontSize: "xs", children: this.state.errorInfo.componentStack }), this.state.error?.stack && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_2.Text, { color: "text-secondary", fontWeight: "medium", mt: 4, mb: 2, children: "Error Stack:" }), (0, jsx_runtime_1.jsx)(react_2.Text, { color: "text-muted", fontSize: "xs", children: this.state.error.stack })] }))] })), (0, jsx_runtime_1.jsx)(react_2.Button, { colorScheme: "blue", onClick: this.handleReset, alignSelf: "flex-start", "aria-label": "Try again after error", children: "Try Again" })] }) }));
        }
        return this.props.children;
    }
}
exports.ErrorBoundary = ErrorBoundary;
exports.default = ErrorBoundary;
//# sourceMappingURL=ErrorBoundary.js.map