"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorBoundary = exports.UIError = exports.UI_ERROR_CODES = exports.errorUtils = exports.ERROR_CODES = exports.createError = void 0;
exports.createComponentError = createComponentError;
exports.useErrorHandler = useErrorHandler;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
 * React-Compatible Error Handling Adapter for Shared Utilities
 *
 * This file provides a React-compatible error handling implementation
 * that uses the shared error utilities from @bluefly/llmcli/shared.
 */
const react_1 = __importDefault(require("react"));
const shared_1 = require("@bluefly/llmcli/shared");
Object.defineProperty(exports, "createError", { enumerable: true, get: function () { return shared_1.createError; } });
Object.defineProperty(exports, "ERROR_CODES", { enumerable: true, get: function () { return shared_1.ERROR_CODES; } });
Object.defineProperty(exports, "errorUtils", { enumerable: true, get: function () { return shared_1.errorUtils; } });
const logger_adapter_1 = require("./logger-adapter");
/**
 * React-specific error codes that extend shared error codes
 */
exports.UI_ERROR_CODES = {
    ...shared_1.ERROR_CODES,
    COMPONENT_ERROR: 'COMPONENT_ERROR',
    RENDER_ERROR: 'RENDER_ERROR',
    HOOK_ERROR: 'HOOK_ERROR',
    STATE_ERROR: 'STATE_ERROR',
    PROP_VALIDATION_ERROR: 'PROP_VALIDATION_ERROR',
    CONTEXT_ERROR: 'CONTEXT_ERROR'
};
/**
 * React UI error with enhanced properties
 */
class UIError extends Error {
    constructor(options) {
        super(options.message);
        this.name = 'UIError';
        this.code = options.code || exports.UI_ERROR_CODES.COMPONENT_ERROR;
        this.statusCode = options.statusCode;
        this.component = options.component;
        this.details = options.details;
        this.props = options.props;
        this.state = options.state;
    }
    /**
     * Convert to BlueflyError
     */
    toBlueflyError() {
        return (0, shared_1.createError)(this.message, this.code, this.statusCode, {
            component: this.component,
            ...this.details,
            props: this.props,
            state: this.state
        });
    }
}
exports.UIError = UIError;
/**
 * Create a component error
 */
function createComponentError(message, component, options = {}) {
    return new UIError({
        message,
        code: options.code || exports.UI_ERROR_CODES.COMPONENT_ERROR,
        component,
        props: options.props,
        state: options.state,
        details: options.details
    });
}
class ErrorBoundary extends react_1.default.Component {
    constructor(props) {
        super(props);
        this.state = {
            hasError: false,
            error: null
        };
    }
    static getDerivedStateFromError(error) {
        // Convert to UIError if it's not already
        const uiError = error instanceof UIError
            ? error
            : new UIError({
                message: error.message,
                details: { originalError: error }
            });
        return { hasError: true, error: uiError };
    }
    componentDidCatch(error, errorInfo) {
        // Convert to UIError
        const uiError = this.state.error || new UIError({
            message: error.message,
            component: errorInfo.componentStack.split('\n')[1]?.trim() || 'Unknown',
            details: {
                componentStack: errorInfo.componentStack,
                originalError: error
            }
        });
        // Log error
        logger_adapter_1.logger.error('React component error', uiError, {
            componentStack: errorInfo.componentStack
        });
        // Call onError if provided
        if (this.props.onError) {
            this.props.onError(uiError, errorInfo);
        }
    }
    render() {
        if (this.state.hasError) {
            if (this.props.fallback) {
                if (typeof this.props.fallback === 'function') {
                    return this.props.fallback(this.state.error);
                }
                return this.props.fallback;
            }
            // Default fallback UI
            return ((0, jsx_runtime_1.jsxs)("div", { style: {
                    padding: '20px',
                    margin: '20px',
                    border: '1px solid #f5c6cb',
                    borderRadius: '4px',
                    backgroundColor: '#f8d7da',
                    color: '#721c24'
                }, children: [(0, jsx_runtime_1.jsx)("h3", { children: "Something went wrong" }), process.env.NODE_ENV !== 'production' && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("p", { children: this.state.error?.message }), (0, jsx_runtime_1.jsxs)("details", { children: [(0, jsx_runtime_1.jsx)("summary", { children: "Error details" }), (0, jsx_runtime_1.jsx)("pre", { style: { whiteSpace: 'pre-wrap' }, children: this.state.error?.stack })] })] }))] }));
        }
        return this.props.children;
    }
}
exports.ErrorBoundary = ErrorBoundary;
/**
 * Custom hook for error handling
 */
function useErrorHandler() {
    const componentName = getCallerComponentName();
    const handleError = react_1.default.useCallback((error, component) => {
        const uiError = error instanceof UIError
            ? error
            : new UIError({
                message: error?.message || 'An error occurred',
                component: component || componentName || 'Unknown',
                details: { originalError: error }
            });
        logger_adapter_1.logger.error('Error handled', uiError);
        return uiError;
    }, [componentName]);
    const throwError = react_1.default.useCallback((message, options) => {
        throw new UIError({
            message,
            component: componentName || 'Unknown',
            details: options
        });
    }, [componentName]);
    return { handleError, throwError };
}
/**
 * Try to determine the calling component name
 */
function getCallerComponentName() {
    try {
        const err = new Error();
        const stackLines = err.stack?.split('\n') || [];
        // Find the first capitalized name in the stack which likely represents a component
        for (let i = 2; i < stackLines.length; i++) {
            const matches = stackLines[i].match(/at ([A-Z][a-zA-Z0-9]+)/);
            if (matches && matches[1]) {
                return matches[1];
            }
        }
        return null;
    }
    catch (e) {
        return null;
    }
}
// Create and export error adapter functions
exports.default = {
    UIError,
    ErrorBoundary,
    createComponentError,
    useErrorHandler,
    UI_ERROR_CODES: exports.UI_ERROR_CODES
};
//# sourceMappingURL=error-adapter.js.map