const db = require('../dbProxy');

/**
 * 统一错误处理模块
 * 负责错误分类、记录、恢复决策
 */
class ErrorHandler {
    /**
     * 可重试的错误类型
     */
    static RETRYABLE_ERRORS = [
        'ETIMEDOUT',
        'ECONNRESET',
        'ENOTFOUND',
        'NetworkError',
        'MQTT客户端未初始化',
        '设备离线',
        '超时'
    ];

    /**
     * 处理错误
     * @param {Error} error - 错误对象
     * @param {Object} context - 上下文信息
     * @returns {Object} 错误处理结果
     */
    static async handleError(error, context = {}) {
        const errorInfo = {
            message: error.message || '未知错误',
            stack: error.stack || '',
            code: error.code || '',
            context: {
                task_id: context.task_id,
                sn_code: context.sn_code,
                taskType: context.taskType,
                ...context
            },
            timestamp: new Date().toISOString(),
            isRetryable: this.isRetryableError(error)
        };

        // 记录到日志
        console.error(`[错误处理] ${errorInfo.message}`, {
            context: errorInfo.context,
            isRetryable: errorInfo.isRetryable,
            stack: errorInfo.stack
        });

        // 错误信息已通过 console.error 记录到控制台日志

        return errorInfo;
    }

    /**
     * 判断错误是否可重试
     * @param {Error} error - 错误对象
     * @returns {boolean}
     */
    static isRetryableError(error) {
        if (!error) return false;

        const errorMessage = (error.message || '').toLowerCase();
        const errorCode = error.code || '';

        // 检查错误代码
        if (this.RETRYABLE_ERRORS.some(code => errorCode === code)) {
            return true;
        }

        // 检查错误消息
        return this.RETRYABLE_ERRORS.some(code => 
            errorMessage.includes(code.toLowerCase())
        );
    }

    /**
     * 计算重试延迟（指数退避）
     * @param {number} retryCount - 当前重试次数
     * @param {number} baseDelay - 基础延迟（毫秒）
     * @param {number} maxDelay - 最大延迟（毫秒）
     * @returns {number} 延迟时间（毫秒）
     */
    static calculateRetryDelay(retryCount, baseDelay = 1000, maxDelay = 30000) {
        const delay = Math.min(baseDelay * Math.pow(2, retryCount - 1), maxDelay);
        return delay;
    }

    /**
     * 创建可重试错误
     * @param {string} message - 错误消息
     * @param {Object} context - 上下文
     * @returns {Error}
     */
    static createRetryableError(message, context = {}) {
        const error = new Error(message);
        error.code = 'RETRYABLE';
        error.context = context;
        error.isRetryable = true;
        return error;
    }

    /**
     * 创建致命错误
     * @param {string} message - 错误消息
     * @param {Object} context - 上下文
     * @returns {Error}
     */
    static createFatalError(message, context = {}) {
        const error = new Error(message);
        error.code = 'FATAL';
        error.context = context;
        error.isRetryable = false;
        return error;
    }
}

module.exports = ErrorHandler;

