import { ZodError } from 'zod';
import logger from '../logger.js';
import { AggregatedValidationError } from './AggregatedValidationError.js';

class ErrorHandler {
    error;
    constructor(error) {
        this.error = error;
        logger.error(`Error: ${JSON.stringify(error)}`);
    }
    formatError() {
        return this.handleError();
    }
    handleError() {
        const err = this.error;
        // 1. Zod
        if (err instanceof ZodError) {
            const issues = err.issues.map((i) => i.message).join('. ');
            return {
                status: 500,
                userMessage: `Schema validation error: ${issues}`,
            };
        }
        // 2. AggregatedValidationError
        if (err instanceof AggregatedValidationError) {
            return {
                status: 500,
                userMessage: [
                    err.message,
                    ...err.details.map((detail) => {
                        const issues = detail.issues.map((i) => i.message).join('. ');
                        let prefix = '';
                        if (detail.type)
                            prefix += `Type: '${detail.type}'. `;
                        if (detail.id)
                            prefix += `ID: '${detail.id}'. `;
                        return `${prefix}Issues: ${issues}`;
                    }),
                ],
            };
        }
        // 3. SuperAgent / WireMock
        if (this.isSuperAgentError(err)) {
            const status = typeof err.status === 'number' ? err.status : 500;
            // 1. Prefer response.body if present
            let payload = err.response?.body;
            // 2. Otherwise try to parse text as JSON
            if (payload === undefined) {
                payload = this.tryParseJson(err.text);
            }
            // 3. If we now have a structured error payload
            if (this.isErrorPayload(payload)) {
                const { userMessage, developerMessage, moreInfo } = payload;
                return {
                    status,
                    ...(userMessage !== undefined && { userMessage }),
                    ...(developerMessage !== undefined && { developerMessage }),
                    ...(moreInfo !== undefined && { moreInfo }),
                };
            }
            // 4. Transport-level fallback
            return {
                status,
                userMessage: err.message,
            };
        }
        if (typeof err === 'object' &&
            err !== null &&
            'message' in err &&
            typeof err.message === 'string') {
            return {
                status: 500,
                userMessage: err.message,
            };
        }
        // 5. Unknown
        return {
            status: 500,
            developerMessage: 'Unknown error',
        };
    }
    isSuperAgentError(error) {
        if (typeof error !== 'object' || error === null)
            return false;
        const e = error;
        return (typeof e['message'] === 'string' &&
            (typeof e['status'] === 'number' || typeof e['text'] !== 'undefined' || typeof e['response'] === 'object'));
    }
    isErrorPayload(value) {
        return (typeof value === 'object' &&
            value !== null &&
            ('userMessage' in value || 'developerMessage' in value || 'moreInfo' in value));
    }
    tryParseJson(value) {
        if (typeof value !== 'string')
            return undefined;
        try {
            return JSON.parse(value);
        }
        catch {
            return undefined;
        }
    }
}

export { ErrorHandler, ErrorHandler as default };
//# sourceMappingURL=ErrorHandler.js.map
