/**
 * 错误处理工具
 */

import { ElMessage, ElNotification } from 'element-plus'

// 错误类型枚举
export enum ErrorType {
  NETWORK = 'NETWORK',
  AUTH = 'AUTH',
  VALIDATION = 'VALIDATION',
  BUSINESS = 'BUSINESS',
  UNKNOWN = 'UNKNOWN'
}

// 错误信息接口
export interface ErrorInfo {
  type: ErrorType
  code?: string | number
  message: string
  details?: any
}

/**
 * 错误分类器
 */
export class ErrorClassifier {
  /**
   * 分析错误类型
   */
  static classify(error: any): ErrorInfo {
    // 网络错误
    if (error.code === 'NETWORK_ERROR' || error.message?.includes('Network Error')) {
      return {
        type: ErrorType.NETWORK,
        code: error.code,
        message: '网络连接失败，请检查网络设置'
      }
    }

    // 认证错误
    if (error.status === 401 || error.code === 401) {
      return {
        type: ErrorType.AUTH,
        code: 401,
        message: '登录已过期，请重新登录'
      }
    }

    // 权限错误
    if (error.status === 403 || error.code === 403) {
      return {
        type: ErrorType.AUTH,
        code: 403,
        message: '没有权限访问该资源'
      }
    }

    // 验证错误
    if (error.status === 400 || error.code === 400) {
      return {
        type: ErrorType.VALIDATION,
        code: 400,
        message: error.message || '请求参数错误'
      }
    }

    // 服务器错误
    if (error.status >= 500 || error.code >= 500) {
      return {
        type: ErrorType.NETWORK,
        code: error.status || error.code,
        message: '服务器内部错误，请稍后重试'
      }
    }

    // 业务错误
    if (error.message) {
      return {
        type: ErrorType.BUSINESS,
        code: error.code,
        message: error.message,
        details: error
      }
    }

    // 未知错误
    return {
      type: ErrorType.UNKNOWN,
      message: '发生未知错误，请稍后重试',
      details: error
    }
  }
}

/**
 * 错误处理器
 */
export class ErrorHandler {
  /**
   * 处理错误
   */
  static handle(error: any, options: {
    showMessage?: boolean
    showNotification?: boolean
    logError?: boolean
  } = {}) {
    const {
      showMessage = true,
      showNotification = false,
      logError = true
    } = options

    const errorInfo = ErrorClassifier.classify(error)

    // 记录错误日志
    if (logError) {
      console.error('错误处理:', {
        type: errorInfo.type,
        code: errorInfo.code,
        message: errorInfo.message,
        details: errorInfo.details,
        originalError: error
      })
    }

    // 显示错误消息
    if (showMessage) {
      this.showErrorMessage(errorInfo)
    }

    // 显示错误通知
    if (showNotification) {
      this.showErrorNotification(errorInfo)
    }

    return errorInfo
  }

  /**
   * 显示错误消息
   */
  private static showErrorMessage(errorInfo: ErrorInfo) {
    switch (errorInfo.type) {
      case ErrorType.NETWORK:
        ElMessage.error({
          message: errorInfo.message,
          duration: 5000
        })
        break
      case ErrorType.AUTH:
        ElMessage.warning({
          message: errorInfo.message,
          duration: 3000
        })
        break
      case ErrorType.VALIDATION:
        ElMessage.warning({
          message: errorInfo.message,
          duration: 3000
        })
        break
      case ErrorType.BUSINESS:
        ElMessage.error({
          message: errorInfo.message,
          duration: 4000
        })
        break
      default:
        ElMessage.error({
          message: errorInfo.message,
          duration: 4000
        })
    }
  }

  /**
   * 显示错误通知
   */
  private static showErrorNotification(errorInfo: ErrorInfo) {
    ElNotification.error({
      title: '错误提示',
      message: errorInfo.message,
      duration: 5000
    })
  }

  /**
   * 处理认证相关错误
   */
  static handleAuthError(error: any) {
    const errorInfo = this.handle(error, {
      showMessage: true,
      logError: true
    })

    // 如果是认证错误，可能需要跳转到登录页
    if (errorInfo.type === ErrorType.AUTH && errorInfo.code === 401) {
      // 清除本地认证信息
      localStorage.removeItem('access_token')
      localStorage.removeItem('refresh_token')
      localStorage.removeItem('user_info')
      
      // 延迟跳转，让用户看到错误消息
      setTimeout(() => {
        window.location.href = '/login'
      }, 2000)
    }

    return errorInfo
  }

  /**
   * 处理API请求错误
   */
  static handleApiError(error: any, context?: string) {
    const contextMessage = context ? `${context}: ` : ''
    
    const errorInfo = this.handle(error, {
      showMessage: true,
      logError: true
    })

    // 添加上下文信息
    if (context) {
      console.error(`${contextMessage}`, errorInfo)
    }

    return errorInfo
  }

  /**
   * 处理表单验证错误
   */
  static handleValidationError(error: any, fieldName?: string) {
    let message = error.message || '表单验证失败'
    
    if (fieldName) {
      message = `${fieldName}: ${message}`
    }

    ElMessage.warning({
      message,
      duration: 3000
    })

    return {
      type: ErrorType.VALIDATION,
      message,
      details: error
    }
  }
}

/**
 * 错误处理装饰器
 */
export function handleError(options?: {
  showMessage?: boolean
  showNotification?: boolean
  logError?: boolean
}) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value

    descriptor.value = async function (...args: any[]) {
      try {
        return await originalMethod.apply(this, args)
      } catch (error) {
        ErrorHandler.handle(error, options)
        throw error
      }
    }

    return descriptor
  }
}

// 导出常用方法
export const handleApiError = ErrorHandler.handleApiError
export const handleAuthError = ErrorHandler.handleAuthError
export const handleValidationError = ErrorHandler.handleValidationError
