/**
 * Foliko Error - 统一错误处理系统
 * 标准化项目中的所有错误类型
 */

/**
 * Foliko 错误基类
 */
class FolikoError extends Error {
  /**
   * @param {string} message - 错误消息
   * @param {Object} [options]
   * @param {string} [options.code] - 错误代码
   * @param {Object} [options.context] - 错误上下文
   * @param {string} [options.stack] - 自定义堆栈
   */
  constructor(message, options = {}) {
    super(message);
    this.name = this.constructor.name;
    this.code = options.code || 'FOLIKO_ERROR';
    this.context = options.context || {};

    // 保留原始堆栈跟踪
    if (options.stack) {
      this.stack = options.stack;
    } else {
      Error.captureStackTrace(this, this.constructor);
    }
  }

  /**
   * 将错误转换为 JSON
   * @returns {Object}
   */
  toJSON() {
    return {
      name: this.name,
      message: this.message,
      code: this.code,
      context: this.context,
      stack: this.stack,
    };
  }
}

/**
 * 插件相关错误
 */
class PluginError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'PLUGIN_ERROR',
      context: options.context,
    });
  }
}

/**
 * 工具执行错误
 */
class ToolError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'TOOL_ERROR',
      context: {
        toolName: options.toolName,
        args: options.args,
        ...options.context,
      },
    });
  }
}

/**
 * AI 执行错误
 */
class AIError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'AI_ERROR',
      context: {
        model: options.model,
        provider: options.provider,
        statusCode: options.statusCode,
        ...options.context,
      },
    });
  }
}

/**
 * 会话相关错误
 */
class SessionError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'SESSION_ERROR',
      context: {
        sessionId: options.sessionId,
        ...options.context,
      },
    });
  }
}

/**
 * 配置错误
 */
class ConfigError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'CONFIG_ERROR',
      context: {
        configKey: options.configKey,
        expected: options.expected,
        actual: options.actual,
        ...options.context,
      },
    });
  }
}

/**
 * 工作流执行错误
 */
class WorkflowError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'WORKFLOW_ERROR',
      context: {
        workflowName: options.workflowName,
        stepName: options.stepName,
        stepIndex: options.stepIndex,
        ...options.context,
      },
    });
  }
}

/**
 * 验证错误
 */
class ValidationError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'VALIDATION_ERROR',
      context: {
        field: options.field,
        value: options.value,
        expected: options.expected,
        ...options.context,
      },
    });
  }
}

/**
 * 工具未找到错误
 */
class ToolNotFoundError extends ToolError {
  constructor(toolName) {
    super(`Tool not found: ${toolName}`, { toolName });
    this.code = 'TOOL_NOT_FOUND';
  }
}

/**
 * 插件未找到错误
 */
class PluginNotFoundError extends PluginError {
  constructor(pluginName) {
    super(`Plugin not found: ${pluginName}`, {
      context: { pluginName },
    });
    this.code = 'PLUGIN_NOT_FOUND';
  }
}

/**
 * 检查错误类型
 * @param {Error} error
 * @param {Function} ErrorClass
 * @returns {boolean}
 */

/**
 * 网络相关错误
 */
class NetworkError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'NETWORK_ERROR',
      context: {
        host: options.host,
        port: options.port,
        code: options.code,
        ...options.context,
      },
    });
  }
}

/**
 * 认证/授权错误
 */
class AuthError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'AUTH_ERROR',
      context: {
        authType: options.authType,
        userId: options.userId,
        ...options.context,
      },
    });
  }
}

/**
 * 限流错误
 */
class RateLimitError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'RATE_LIMIT_ERROR',
      context: {
        retryAfter: options.retryAfter,
        limit: options.limit,
        ...options.context,
      },
    });
  }
}

/**
 * 超时错误
 */
class TimeoutError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'TIMEOUT_ERROR',
      context: {
        timeout: options.timeout,
        operation: options.operation,
        ...options.context,
      },
    });
  }
}

/**
 * 文件系统错误
 */
class FileSystemError extends FolikoError {
  constructor(message, options = {}) {
    super(message, {
      code: 'FS_ERROR',
      context: {
        path: options.path,
        operation: options.operation,
        ...options.context,
      },
    });
  }
}

function isErrorOfType(error, ErrorClass) {
  return error instanceof ErrorClass;
}

/**
 * 安全地获取错误信息
 * @param {Error} error
 * @returns {Object}
 */
function safeErrorInfo(error) {
  if (error instanceof FolikoError) {
    return error.toJSON();
  }
  return {
    name: error.name || 'Error',
    message: error.message,
    code: 'UNKNOWN_ERROR',
    context: {},
    stack: error.stack,
  };
}

/**
 * 错误工厂函数 - 根据错误类型快速创建错误
 * @param {string} type - 错误类型
 * @param {string} message - 错误消息
 * @param {Object} options - 错误选项
 * @returns {FolikoError}
 */
function createError(type, message, options = {}) {
  const errorClasses = {
    plugin: PluginError,
    tool: ToolError,
    ai: AIError,
    session: SessionError,
    config: ConfigError,
    workflow: WorkflowError,
    validation: ValidationError,
    network: NetworkError,
    auth: AuthError,
    rateLimit: RateLimitError,
    timeout: TimeoutError,
    fs: FileSystemError,
  };
  const ErrorClass = errorClasses[type] || FolikoError;
  return new ErrorClass(message, options);
}

/**
 * 判断错误是否可重试
 * @param {Error} error
 * @returns {boolean}
 */
function isRetryable(error) {
  if (error instanceof RateLimitError) return true;
  if (error instanceof TimeoutError) return true;
  if (error instanceof NetworkError) return true;
  if (error instanceof FolikoError) {
    const retryableCodes = ['RATE_LIMIT_ERROR', 'TIMEOUT_ERROR', 'NETWORK_ERROR'];
    return retryableCodes.includes(error.code);
  }
  return false;
}

/**
 * 获取用户友好的错误消息
 * @param {Error} error
 * @returns {string}
 */
function getFriendlyMessage(error) {
  if (error instanceof FolikoError) {
    const messages = {
      PLUGIN_NOT_FOUND: '插件未找到，请检查配置',
      TOOL_NOT_FOUND: '工具未找到，请检查工具名称',
      CONFIG_ERROR: '配置错误，请检查配置文件',
      VALIDATION_ERROR: '输入验证失败，请检查输入数据',
      RATE_LIMIT_ERROR: '请求过于频繁，请稍后再试',
      TIMEOUT_ERROR: '请求超时，请检查网络连接',
      NETWORK_ERROR: '网络错误，请检查网络连接',
      AUTH_ERROR: '认证失败，请检查凭据是否正确',
    };
    return messages[error.code] || error.message;
  }
  return error.message || '发生未知错误';
}

module.exports = {
  FolikoError,
  PluginError,
  ToolError,
  AIError,
  SessionError,
  ConfigError,
  WorkflowError,
  ValidationError,
  ToolNotFoundError,
  PluginNotFoundError,
  NetworkError,
  AuthError,
  RateLimitError,
  TimeoutError,
  FileSystemError,
  isErrorOfType,
  safeErrorInfo,
  createError,
  isRetryable,
  getFriendlyMessage,
};
