/**
 * AppError - 应用统一错误模型
 * 
 * 用于统一处理后端业务错误和前端运行时错误
 */

/**
 * 错误类型常量
 */
export const ErrorType = {
  /** 业务错误 - 后端返回的业务逻辑错误 */
  BUSINESS: 'BUSINESS',
  /** 网络错误 - 请求失败、超时等 */
  NETWORK: 'NETWORK',
  /** 认证错误 - 401 未登录或 token 过期 */
  AUTH: 'AUTH',
  /** 权限错误 - 403 无权限访问 */
  FORBIDDEN: 'FORBIDDEN',
  /** 资源不存在 - 404 */
  NOT_FOUND: 'NOT_FOUND',
  /** 验证错误 - 表单校验失败 */
  VALIDATION: 'VALIDATION',
  /** 未知错误 */
  UNKNOWN: 'UNKNOWN',
} as const

export type ErrorTypeValue = typeof ErrorType[keyof typeof ErrorType]

/**
 * 应用错误类
 */
export class AppError extends Error {
  /** 错误码 */
  readonly code: number
  
  /** HTTP 状态码 */
  readonly status: number
  
  /** 错误类型 */
  readonly type: ErrorTypeValue
  
  /** 原始错误 */
  readonly cause?: Error

  constructor(
    code: number,
    message: string,
    options?: {
      status?: number
      type?: ErrorTypeValue
      cause?: Error
    }
  ) {
    super(message)
    this.name = 'AppError'
    this.code = code
    this.status = options?.status ?? 500
    this.type = options?.type ?? ErrorType.BUSINESS
    this.cause = options?.cause

    // 确保 instanceof 正常工作
    Object.setPrototypeOf(this, AppError.prototype)
  }

  /**
   * 从后端响应创建错误
   */
  static fromResponse(response: { code: number; message: string }, status: number): AppError {
    let type: ErrorTypeValue = ErrorType.BUSINESS

    if (status === 401) {
      type = ErrorType.AUTH
    } else if (status === 403) {
      type = ErrorType.FORBIDDEN
    } else if (status === 404) {
      type = ErrorType.NOT_FOUND
    } else if (status >= 500) {
      type = ErrorType.NETWORK
    }

    return new AppError(response.code, response.message, { status, type })
  }

  /**
   * 创建网络错误
   */
  static network(message: string, cause?: Error): AppError {
    return new AppError(0, message, {
      status: 0,
      type: ErrorType.NETWORK,
      cause,
    })
  }

  /**
   * 创建认证错误
   */
  static auth(message: string = '请先登录'): AppError {
    return new AppError(401, message, {
      status: 401,
      type: ErrorType.AUTH,
    })
  }

  /**
   * 创建权限错误
   */
  static forbidden(message: string = '无权限访问'): AppError {
    return new AppError(403, message, {
      status: 403,
      type: ErrorType.FORBIDDEN,
    })
  }

  /**
   * 创建验证错误
   */
  static validation(message: string): AppError {
    return new AppError(400, message, {
      status: 400,
      type: ErrorType.VALIDATION,
    })
  }

  /**
   * 判断是否为认证错误
   */
  isAuthError(): boolean {
    return this.type === ErrorType.AUTH || this.status === 401
  }

  /**
   * 判断是否为权限错误
   */
  isForbidden(): boolean {
    return this.type === ErrorType.FORBIDDEN || this.status === 403
  }

  /**
   * 判断是否为网络错误
   */
  isNetworkError(): boolean {
    return this.type === ErrorType.NETWORK
  }

  /**
   * 获取用户友好的错误消息
   */
  getUserMessage(): string {
    switch (this.type) {
      case ErrorType.NETWORK:
        return '网络连接失败，请检查网络后重试'
      case ErrorType.AUTH:
        return '登录已过期，请重新登录'
      case ErrorType.FORBIDDEN:
        return '您没有权限执行此操作'
      case ErrorType.NOT_FOUND:
        return '请求的资源不存在'
      case ErrorType.VALIDATION:
        return this.message
      default:
        return this.message || '操作失败，请稍后重试'
    }
  }
}

/**
 * 判断是否为 AppError
 */
export function isAppError(error: unknown): error is AppError {
  return error instanceof AppError
}
