/**
 * 错误处理工具类
 * 提供统一的错误处理和用户友好的错误消息
 */

export interface ErrorInfo {
  code: string;
  message: string;
  details?: string;
  suggestions?: string[];
}

export class ErrorHandler {
  /**
   * 解析Tauri命令错误
   */
  static parseTauriError(error: any): ErrorInfo {
    const errorStr = String(error);
    
    // 工作流模板相关错误
    if (errorStr.includes('工作流模板不存在')) {
      return {
        code: 'WORKFLOW_TEMPLATE_NOT_FOUND',
        message: '工作流模板不存在',
        details: '请确认工作流模板ID是否正确',
        suggestions: [
          '检查工作流模板是否已被删除',
          '刷新页面重新加载模板列表',
          '联系管理员确认模板状态'
        ]
      };
    }

    // 输入数据验证错误
    if (errorStr.includes('输入数据验证失败')) {
      const details = errorStr.split('输入数据验证失败:')[1]?.trim();
      return {
        code: 'INPUT_VALIDATION_FAILED',
        message: '输入数据验证失败',
        details: details || '请检查输入的参数是否符合要求',
        suggestions: [
          '检查必填字段是否已填写',
          '确认数值字段的取值范围',
          '验证文本字段的格式要求',
          '检查选择字段的选项是否正确'
        ]
      };
    }

    // 节点映射错误
    if (errorStr.includes('节点映射') || errorStr.includes('node mapping')) {
      return {
        code: 'NODE_MAPPING_ERROR',
        message: '节点映射配置错误',
        details: '工作流的节点映射配置有问题',
        suggestions: [
          '检查UI字段是否正确映射到ComfyUI节点',
          '确认目标节点ID是否存在于工作流中',
          '验证输入字段名称是否正确',
          '检查数据转换类型是否匹配'
        ]
      };
    }

    // ComfyUI连接错误
    if (errorStr.includes('ComfyUI') && (errorStr.includes('连接') || errorStr.includes('connection'))) {
      return {
        code: 'COMFYUI_CONNECTION_ERROR',
        message: 'ComfyUI服务连接失败',
        details: '无法连接到ComfyUI服务器',
        suggestions: [
          '检查ComfyUI服务是否正在运行',
          '确认ComfyUI服务器地址和端口配置',
          '检查网络连接是否正常',
          '查看ComfyUI服务器日志'
        ]
      };
    }

    // 工作流执行错误
    if (errorStr.includes('执行工作流失败') || errorStr.includes('workflow execution failed')) {
      return {
        code: 'WORKFLOW_EXECUTION_FAILED',
        message: '工作流执行失败',
        details: '工作流在执行过程中遇到错误',
        suggestions: [
          '检查输入参数是否正确',
          '确认ComfyUI工作流配置是否有效',
          '查看ComfyUI服务器日志获取详细错误信息',
          '尝试使用默认参数重新执行'
        ]
      };
    }

    // 数据库错误
    if (errorStr.includes('数据库') || errorStr.includes('database')) {
      return {
        code: 'DATABASE_ERROR',
        message: '数据库操作失败',
        details: '数据库操作过程中发生错误',
        suggestions: [
          '检查数据库连接是否正常',
          '确认数据库文件是否存在',
          '尝试重启应用程序',
          '检查磁盘空间是否充足'
        ]
      };
    }

    // 文件系统错误
    if (errorStr.includes('文件') || errorStr.includes('file') || errorStr.includes('路径') || errorStr.includes('path')) {
      return {
        code: 'FILE_SYSTEM_ERROR',
        message: '文件系统操作失败',
        details: '文件读取、写入或路径访问失败',
        suggestions: [
          '检查文件路径是否正确',
          '确认文件是否存在',
          '检查文件访问权限',
          '确认磁盘空间是否充足'
        ]
      };
    }

    // 网络错误
    if (errorStr.includes('网络') || errorStr.includes('network') || errorStr.includes('timeout')) {
      return {
        code: 'NETWORK_ERROR',
        message: '网络请求失败',
        details: '网络连接或请求超时',
        suggestions: [
          '检查网络连接是否正常',
          '确认服务器地址是否正确',
          '尝试稍后重新请求',
          '检查防火墙设置'
        ]
      };
    }

    // 权限错误
    if (errorStr.includes('权限') || errorStr.includes('permission') || errorStr.includes('access denied')) {
      return {
        code: 'PERMISSION_ERROR',
        message: '权限不足',
        details: '没有足够的权限执行此操作',
        suggestions: [
          '检查文件或目录的访问权限',
          '尝试以管理员身份运行应用',
          '确认用户账户权限设置',
          '联系系统管理员'
        ]
      };
    }

    // 默认错误
    return {
      code: 'UNKNOWN_ERROR',
      message: '未知错误',
      details: errorStr,
      suggestions: [
        '尝试重新执行操作',
        '检查应用程序日志',
        '重启应用程序',
        '联系技术支持'
      ]
    };
  }

  /**
   * 格式化错误消息用于显示
   */
  static formatErrorMessage(errorInfo: ErrorInfo): string {
    let message = errorInfo.message;
    
    if (errorInfo.details) {
      message += `\n\n详细信息：${errorInfo.details}`;
    }
    
    if (errorInfo.suggestions && errorInfo.suggestions.length > 0) {
      message += '\n\n建议解决方案：';
      errorInfo.suggestions.forEach((suggestion, index) => {
        message += `\n${index + 1}. ${suggestion}`;
      });
    }
    
    return message;
  }

  /**
   * 显示错误通知
   */
  static showErrorNotification(error: any, title: string = '操作失败') {
    const errorInfo = this.parseTauriError(error);
    const message = this.formatErrorMessage(errorInfo);
    
    // 这里可以集成具体的通知组件
    console.error(`${title}:`, message);
    
    // 如果有全局通知系统，可以在这里调用
    // notificationService.error(title, message);
    
    return errorInfo;
  }

  /**
   * 检查是否为可重试的错误
   */
  static isRetryableError(errorInfo: ErrorInfo): boolean {
    const retryableCodes = [
      'COMFYUI_CONNECTION_ERROR',
      'NETWORK_ERROR',
      'WORKFLOW_EXECUTION_FAILED'
    ];
    
    return retryableCodes.includes(errorInfo.code);
  }

  /**
   * 检查是否为用户输入错误
   */
  static isUserInputError(errorInfo: ErrorInfo): boolean {
    const userInputCodes = [
      'INPUT_VALIDATION_FAILED',
      'NODE_MAPPING_ERROR'
    ];
    
    return userInputCodes.includes(errorInfo.code);
  }

  /**
   * 获取错误的严重程度
   */
  static getErrorSeverity(errorInfo: ErrorInfo): 'low' | 'medium' | 'high' | 'critical' {
    switch (errorInfo.code) {
      case 'INPUT_VALIDATION_FAILED':
      case 'NODE_MAPPING_ERROR':
        return 'low';
      
      case 'COMFYUI_CONNECTION_ERROR':
      case 'NETWORK_ERROR':
      case 'WORKFLOW_EXECUTION_FAILED':
        return 'medium';
      
      case 'DATABASE_ERROR':
      case 'FILE_SYSTEM_ERROR':
      case 'PERMISSION_ERROR':
        return 'high';
      
      case 'WORKFLOW_TEMPLATE_NOT_FOUND':
      case 'UNKNOWN_ERROR':
      default:
        return 'critical';
    }
  }
}

/**
 * 错误边界组件的错误处理
 */
export const handleComponentError = (error: Error, errorInfo: any) => {
  console.error('组件错误:', error, errorInfo);
  
  // 可以在这里发送错误报告到监控服务
  // errorReportingService.captureException(error, { extra: errorInfo });
};

/**
 * Promise 错误处理装饰器
 */
export const withErrorHandling = <T extends (...args: any[]) => Promise<any>>(
  fn: T,
  errorHandler?: (error: any) => void
): T => {
  return (async (...args: any[]) => {
    try {
      return await fn(...args);
    } catch (error) {
      if (errorHandler) {
        errorHandler(error);
      } else {
        ErrorHandler.showErrorNotification(error);
      }
      throw error;
    }
  }) as T;
};
