/**
 * 框架自定义错误类
 */

export class AutomationError extends Error {
  public context: any;
  public timestamp: Date;

  constructor(message: string, context: any = {}) {
    super(message);
    this.name = 'AutomationError';
    this.context = context;
    this.timestamp = new Date();
    
    // 维持正确的原型链
    Object.setPrototypeOf(this, AutomationError.prototype);
  }

  toJSON(): any {
    return {
      name: this.name,
      message: this.message,
      context: this.context,
      timestamp: this.timestamp,
      stack: this.stack
    };
  }
}

export class ElementNotFoundError extends AutomationError {
  public selector: any;

  constructor(selector: any, context: any = {}) {
    super(`元素未找到: ${JSON.stringify(selector)}`, context);
    this.name = 'ElementNotFoundError';
    this.selector = selector;
    Object.setPrototypeOf(this, ElementNotFoundError.prototype);
  }
}

export class TimeoutError extends AutomationError {
  public operation: string;
  public timeout: number;

  constructor(operation: string, timeout: number, context: any = {}) {
    super(`操作超时: ${operation} (${timeout}ms)`, context);
    this.name = 'TimeoutError';
    this.operation = operation;
    this.timeout = timeout;
    Object.setPrototypeOf(this, TimeoutError.prototype);
  }
}

export class ValidationError extends AutomationError {
  public expected: any;
  public actual: any;

  constructor(message: string, expected: any, actual: any, context: any = {}) {
    super(message, context);
    this.name = 'ValidationError';
    this.expected = expected;
    this.actual = actual;
    Object.setPrototypeOf(this, ValidationError.prototype);
  }
}

export class ConfigurationError extends AutomationError {
  public configPath: string;

  constructor(message: string, configPath: string, context: any = {}) {
    super(message, context);
    this.name = 'ConfigurationError';
    this.configPath = configPath;
    Object.setPrototypeOf(this, ConfigurationError.prototype);
  }
}

export class RetryExhaustedError extends AutomationError {
  public operation: string;
  public attempts: number;

  constructor(operation: string, attempts: number, context: any = {}) {
    super(`重试次数用尽: ${operation} (${attempts} 次尝试)`, context);
    this.name = 'RetryExhaustedError';
    this.operation = operation;
    this.attempts = attempts;
    Object.setPrototypeOf(this, RetryExhaustedError.prototype);
  }
}
