/**
 * 统一错误处理工具
 * 
 * 功能：
 * 1. 错误码到友好提示的映射（中英文）
 * 2. 自动 Toast 提示
 * 3. 字段错误提取
 * 4. 错误类型判断
 */

import { ApiClientError } from './api-client';
import { toast } from './toast';

// ==================== 错误码映射表 ====================

/**
 * 错误码 -> 友好提示映射（中英文）
 */
const ERROR_MESSAGE_MAP: Record<string, { zh: string; en: string }> = {
  // ==================== Manager Relationship Errors ====================
  IAM_MANAGER_LOOP_DETECTED: {
    zh: '检测到汇报关系形成环路，请检查上级设置',
    en: 'Circular reporting chain detected, please check manager settings',
  },
  IAM_MANAGER_SELF_REFERENCE: {
    zh: '不能将自己设为自己的上级',
    en: 'Cannot set yourself as your own manager',
  },

  // ==================== User Errors ====================
  IAM_USER_EMAIL_EXISTS: {
    zh: '该邮箱已被使用，请使用其他邮箱',
    en: 'Email already exists, please use another email',
  },
  IAM_USERNAME_EXISTS: {
    zh: '该用户名已被使用，请使用其他用户名',
    en: 'Username already exists, please use another username',
  },
  IAM_EMPLOYEE_ID_EXISTS: {
    zh: '该员工编号已被使用，请使用其他编号',
    en: 'Employee ID already exists, please use another ID',
  },
  IAM_PASSWORD_TOO_WEAK: {
    zh: '密码不符合复杂度要求：8位以上，至少包含大写字母、小写字母、数字中的2种',
    en: 'Password does not meet complexity requirements: at least 8 characters, including 2 of uppercase, lowercase, and digits',
  },
  IAM_USER_SUSPENDED: {
    zh: '该账号已被停用，请联系管理员',
    en: 'Account has been suspended, please contact administrator',
  },
  IAM_USER_TERMINATED: {
    zh: '该账号已离职，无法登录',
    en: 'Account has been terminated and cannot login',
  },
  IAM_USER_LOCKED: {
    zh: '账号因多次失败登录被锁定，请稍后重试或联系管理员',
    en: 'Account locked due to multiple failed login attempts, please try again later or contact administrator',
  },
  IAM_USER_ALREADY_ACTIVE: {
    zh: '用户已处于激活状态',
    en: 'User is already active',
  },
  IAM_TERMINATED_USER_CANNOT_ACTIVATE: {
    zh: '离职用户无法通过普通接口激活，请联系管理员',
    en: 'Terminated users cannot be activated through normal interface, please contact administrator',
  },
  IAM_INVALID_CREDENTIALS: {
    zh: '用户名或密码错误',
    en: 'Invalid username or password',
  },

  // ==================== Role Errors ====================
  IAM_SYSTEM_ROLE_PROTECTED: {
    zh: '内置角色不可删除',
    en: 'Built-in roles cannot be deleted',
  },
  IAM_ROLE_HAS_USERS: {
    zh: '该角色下有关联用户，无法删除',
    en: 'Role has associated users and cannot be deleted',
  },

  // ==================== Department Errors ====================
  IAM_DEPARTMENT_CODE_EXISTS: {
    zh: '该部门编码已存在，请使用其他编码',
    en: 'Department code already exists, please use another code',
  },
  IAM_DEPARTMENT_HAS_CHILDREN: {
    zh: '该部门下有子部门，无法删除',
    en: 'Department has sub-departments and cannot be deleted',
  },
  IAM_DEPARTMENT_HAS_USERS: {
    zh: '该部门下有成员，无法删除',
    en: 'Department has members and cannot be deleted',
  },

  // ==================== Workflow Role Errors ====================
  IAM_WORKFLOW_ROLE_RESOLVE_EMPTY: {
    zh: '流程角色解析结果为空且无兜底策略，请检查规则配置',
    en: 'Workflow role resolution returned no users and no fallback strategy is configured',
  },

  // ==================== Sync Errors ====================
  IAM_SYNC_IN_PROGRESS: {
    zh: '已有同步任务正在进行，请稍后再试',
    en: 'A sync task is already in progress, please try again later',
  },
  IAM_EXTERNAL_ID_MISMATCH: {
    zh: '外部ID与现有记录冲突，请检查数据源',
    en: 'External ID conflicts with existing record, please check data source',
  },

  // ==================== Token Errors ====================
  IAM_TOKEN_EXPIRED: {
    zh: '登录已过期，请重新登录',
    en: 'Login session expired, please login again',
  },
  IAM_TOKEN_REVOKED: {
    zh: 'Token已被撤销，请重新登录',
    en: 'Token has been revoked, please login again',
  },

  // ==================== Region Errors ====================
  IAM_REGION_CODE_EXISTS: {
    zh: '该区域编码已存在，请使用其他编码',
    en: 'Region code already exists, please use another code',
  },
  IAM_REGION_HAS_DEPARTMENTS: {
    zh: '该区域下有关联组织，无法删除',
    en: 'Region has associated departments and cannot be deleted',
  },
  IAM_ONLY_ROOT_DEPARTMENT_CAN_BE_DEFAULT: {
    zh: '只有顶级组织才能设为区域默认组织',
    en: 'Only top-level organizations can be set as default for a region',
  },

  // ==================== Multi-Department Errors ====================
  IAM_USER_NOT_IN_DEPARTMENT: {
    zh: '用户不属于指定部门',
    en: 'User does not belong to the specified department',
  },
  IAM_USER_ALREADY_IN_DEPARTMENT: {
    zh: '用户已属于该部门',
    en: 'User already belongs to this department',
  },
  IAM_CANNOT_REMOVE_PRIMARY_DEPARTMENT: {
    zh: '不能移除主部门，请先设置其他部门为主部门',
    en: 'Cannot remove primary department, please set another department as primary first',
  },
  IAM_MANAGER_NOT_IN_DEPARTMENT: {
    zh: '上级必须是该部门成员',
    en: 'Manager must be a member of the same department',
  },

  // ==================== Generic HTTP Errors ====================
  HTTP_400: {
    zh: '请求参数错误',
    en: 'Invalid request parameters',
  },
  HTTP_401: {
    zh: '未登录或登录已过期，请重新登录',
    en: 'Not logged in or login session expired, please login again',
  },
  HTTP_403: {
    zh: '无权限访问此资源',
    en: 'No permission to access this resource',
  },
  HTTP_404: {
    zh: '请求的资源不存在',
    en: 'Requested resource not found',
  },
  HTTP_409: {
    zh: '资源冲突，请检查输入',
    en: 'Resource conflict, please check input',
  },
  HTTP_422: {
    zh: '无法处理的请求实体',
    en: 'Unprocessable entity',
  },
  HTTP_500: {
    zh: '服务器内部错误，请稍后重试',
    en: 'Internal server error, please try again later',
  },
  HTTP_502: {
    zh: '网关错误，请稍后重试',
    en: 'Bad gateway, please try again later',
  },
  HTTP_503: {
    zh: '服务暂时不可用，请稍后重试',
    en: 'Service temporarily unavailable, please try again later',
  },

  // ==================== Network Errors ====================
  NETWORK_ERROR: {
    zh: '网络连接失败，请检查网络设置',
    en: 'Network connection failed, please check network settings',
  },
  UNKNOWN_ERROR: {
    zh: '未知错误，请稍后重试',
    en: 'Unknown error, please try again later',
  },

  // ==================== Validation Errors ====================
  VALIDATION_ERROR: {
    zh: '表单验证失败，请检查输入',
    en: 'Form validation failed, please check input',
  },
};

// ==================== 错误处理函数 ====================

/**
 * 获取友好的错误提示
 * @param error API 错误对象
 * @param locale 语言 ('zh' | 'en')
 * @returns 友好的错误提示
 */
export function getFriendlyErrorMessage(
  error: ApiClientError,
  locale: 'zh' | 'en' = 'zh',
): string {
  // 优先使用后端返回的详细消息（通常包含更多上下文信息）
  // 后端消息已经是友好的中文/英文，且包含具体细节（如邮箱地址、用户名等）
  if (error.message && error.message.trim()) {
    return error.message;
  }

  // 如果后端没有消息，使用前端映射作为兜底
  const mapping = ERROR_MESSAGE_MAP[error.code];
  if (mapping) {
    return mapping[locale];
  }

  // 最后兜底：返回错误码或使用通用未知错误翻译
  if (error.code) {
    return error.code;
  }
  return locale === 'zh' ? '未知错误' : 'Unknown error';
}

/**
 * 统一错误处理器 - 自动显示 Toast
 * 
 * 使用场景：
 * ```typescript
 * try {
 *   await someApiCall();
 * } catch (error) {
 *   handleApiError(error, 'zh');  // 自动 toast.error()
 * }
 * ```
 * 
 * @param error 错误对象
 * @param locale 语言 ('zh' | 'en')
 * @param options 选项
 */
export function handleApiError(
  error: any,
  locale: 'zh' | 'en' = 'zh',
  options?: {
    /** 是否显示 Toast（默认 true） */
    showToast?: boolean;
    /** 自定义错误消息前缀 */
    prefix?: string;
    /** 是否显示字段错误（默认 true） */
    showFieldErrors?: boolean;
  },
): void {
  const { showToast = true, prefix, showFieldErrors = true } = options || {};

  // 非 ApiClientError，直接显示
  if (!(error instanceof ApiClientError)) {
    if (showToast) {
      const defaultMessage = locale === 'zh' ? '操作失败' : 'Operation failed';
      toast.error(error?.message || defaultMessage);
    }
    return;
  }

  // 获取友好提示
  let message = getFriendlyErrorMessage(error, locale);

  // 添加前缀
  if (prefix) {
    message = `${prefix}: ${message}`;
  }

  // 显示 Toast
  if (showToast) {
    toast.error(message);
  }

  // 如果是验证错误，显示字段错误（可选）
  if (showFieldErrors && error.isValidationError() && error.errors && error.errors.length > 0) {
    // 对于验证错误，额外显示第一个字段错误
    const firstFieldError = error.errors[0];
    if (firstFieldError && firstFieldError.message) {
      toast.error(firstFieldError.field, { description: firstFieldError.message });
    }
  }
}

/**
 * 提取所有字段错误并格式化为对象
 * 
 * 使用场景：表单验证反馈
 * ```typescript
 * const fieldErrors = extractFieldErrors(error);
 * setErrors(fieldErrors); // { email: '邮箱格式不正确', username: '用户名已被使用' }
 * ```
 * 
 * @param error API 错误对象
 * @returns 字段错误对象
 */
export function extractFieldErrors(error: any): Record<string, string> {
  if (!(error instanceof ApiClientError)) {
    return {};
  }
  return error.getAllFieldErrors();
}

/**
 * 获取特定字段的错误消息
 * 
 * @param error API 错误对象
 * @param field 字段名
 * @returns 错误消息
 */
export function getFieldError(error: any, field: string): string | undefined {
  if (!(error instanceof ApiClientError)) {
    return undefined;
  }
  return error.getFieldError(field);
}

/**
 * 判断是否是特定的业务错误
 * 
 * 使用场景：针对特定错误做特殊处理
 * ```typescript
 * catch (error) {
 *   if (isSpecificError(error, 'IAM_USER_EMAIL_EXISTS')) {
 *     // 特殊处理邮箱已存在的情况
 *   } else {
 *     handleApiError(error);
 *   }
 * }
 * ```
 * 
 * @param error 错误对象
 * @param errorCode 错误码
 * @returns 是否是指定错误
 */
export function isSpecificError(error: any, errorCode: string): boolean {
  return error instanceof ApiClientError && error.code === errorCode;
}

/**
 * 判断是否是冲突错误 (409)
 */
export function isConflictError(error: any): boolean {
  return error instanceof ApiClientError && error.isConflict();
}

/**
 * 判断是否是验证错误 (400)
 */
export function isValidationError(error: any): boolean {
  return error instanceof ApiClientError && error.isValidationError();
}

/**
 * 判断是否是未授权错误 (401)
 */
export function isUnauthorizedError(error: any): boolean {
  return error instanceof ApiClientError && error.isUnauthorized();
}

/**
 * 判断是否是无权限错误 (403)
 */
export function isForbiddenError(error: any): boolean {
  return error instanceof ApiClientError && error.isForbidden();
}

/**
 * 判断是否是资源不存在错误 (404)
 */
export function isNotFoundError(error: any): boolean {
  return error instanceof ApiClientError && error.isNotFound();
}

// ==================== 便捷包装函数 ====================

/**
 * 包装异步操作，自动处理错误
 * 
 * 使用场景：简化 try-catch
 * ```typescript
 * const handleSave = withErrorHandler(async () => {
 *   await saveUser(userData);
 *   toast.success('保存成功');
 * });
 * ```
 * 
 * @param fn 异步函数
 * @param locale 语言
 * @returns 包装后的函数
 */
export function withErrorHandler<T extends (...args: any[]) => Promise<any>>(
  fn: T,
  locale: 'zh' | 'en' = 'zh',
): T {
  return (async (...args: any[]) => {
    try {
      return await fn(...args);
    } catch (error) {
      handleApiError(error, locale);
      throw error; // 重新抛出以便调用方知道发生了错误
    }
  }) as T;
}

// ==================== 导出 ====================

export { ApiClientError } from './api-client';
