/**
 * 解析 API 错误响应，提取友好的错误信息
 */

import { isApiError } from '@/types/api-error'

/**
 * Pydantic 验证错误项
 */
interface ValidationError {
  loc: (string | number)[]
  msg: string
  type: string
  ctx?: Record<string, unknown>
}

/**
 * 字段名称映射（中文化）
 */
const fieldNameMap: Record<string, string> = {
  'api_key': 'API 密钥',
  'priority': '优先级',
  'max_concurrent': '最大并发',
  'rate_limit': '速率限制',
  'daily_limit': '每日限制',
  'monthly_limit': '每月限制',
  'allowed_models': '允许的模型',
  'note': '备注',
  'is_active': '启用状态',
  'endpoint_id': 'Endpoint ID',
  'base_url': 'API 基础 URL',
  'timeout': '超时时间',
  'max_retries': '最大重试次数',
  'weight': '权重',
  'email': '邮箱',
  'username': '用户名',
  'password': '密码',
  'name': '名称',
  'display_name': '显示名称',
  'description': '描述',
  'website': '网站',
  'provider_priority': '提供商优先级',
  'billing_type': '计费类型',
  'monthly_quota_usd': '月度配额',
  'quota_reset_day': '配额重置日',
  'quota_expires_at': '配额过期时间',
  'rpm_limit': 'RPM 限制',
  'cache_ttl_minutes': '缓存 TTL',
  'max_probe_interval_minutes': '最大探测间隔',
}

/**
 * 错误类型映射（中文化）
 */
const errorTypeMap: Record<string, (error: ValidationError) => string> = {
  'string_too_short': (error) => {
    const minLength = error.ctx?.min_length || 10
    return `长度不能少于 ${minLength} 个字符`
  },
  'string_too_long': (error) => {
    const maxLength = error.ctx?.max_length
    return `长度不能超过 ${maxLength} 个字符`
  },
  'value_error.missing': () => '此字段为必填项',
  'missing': () => '此字段为必填项',
  'type_error.none.not_allowed': () => '此字段不能为空',
  'value_error': (error) => error.msg,
  'type_error.integer': () => '必须为整数',
  'type_error.float': () => '必须为数字',
  'value_error.number.not_ge': (error) => {
    const limit = error.ctx?.limit_value
    return limit !== undefined ? `不能小于 ${limit}` : '数值过小'
  },
  'value_error.number.not_le': (error) => {
    const limit = error.ctx?.limit_value
    return limit !== undefined ? `不能大于 ${limit}` : '数值过大'
  },
  'value_error.number.not_gt': (error) => {
    const limit = error.ctx?.limit_value
    return limit !== undefined ? `必须大于 ${limit}` : '数值过小'
  },
  'value_error.number.not_lt': (error) => {
    const limit = error.ctx?.limit_value
    return limit !== undefined ? `必须小于 ${limit}` : '数值过大'
  },
  'less_than_equal': (error) => {
    const limit = error.ctx?.le
    return limit !== undefined ? `不能大于 ${limit}` : '数值过大'
  },
  'greater_than_equal': (error) => {
    const limit = error.ctx?.ge
    return limit !== undefined ? `不能小于 ${limit}` : '数值过小'
  },
  'less_than': (error) => {
    const limit = error.ctx?.lt
    return limit !== undefined ? `必须小于 ${limit}` : '数值过大'
  },
  'greater_than': (error) => {
    const limit = error.ctx?.gt
    return limit !== undefined ? `必须大于 ${limit}` : '数值过小'
  },
  'value_error.email': () => '邮箱格式不正确',
  'value_error.url': () => 'URL 格式不正确',
  'type_error.bool': () => '必须为布尔值（true/false）',
  'type_error.list': () => '必须为数组',
  'type_error.dict': () => '必须为对象',
}

/**
 * 获取字段的中文名称
 */
function getFieldName(loc: (string | number)[]): string {
  if (!loc || loc.length === 0) return '字段'

  const fieldPath = loc.filter(item => item !== 'body').join('.')
  const fieldKey = String(loc[loc.length - 1])

  return fieldNameMap[fieldKey] || fieldPath || '字段'
}

/**
 * 格式化单个验证错误
 */
function formatValidationError(error: ValidationError): string {
  const fieldName = getFieldName(error.loc)
  const errorFormatter = errorTypeMap[error.type]

  if (errorFormatter) {
    const errorMsg = errorFormatter(error)
    return `${fieldName}: ${errorMsg}`
  }

  // 默认格式
  return `${fieldName}: ${error.msg}`
}

/**
 * 解析 API 错误响应
 * @param err 错误对象
 * @param defaultMessage 默认错误信息
 * @returns 格式化的错误信息
 */
export function parseApiError(err: unknown, defaultMessage: string = '操作失败'): string {
  if (!err) return defaultMessage

  // 处理网络错误
  if (!isApiError(err) || !err.response) {
    if (err instanceof Error) {
      return err.message || defaultMessage
    }
    return '无法连接到服务器，请检查网络连接'
  }

  const detail = err.response?.data?.detail

  // 如果没有 detail 字段
  if (!detail) {
    return err.response?.data?.message || err.message || defaultMessage
  }

  // 1. 处理 Pydantic 验证错误（数组格式）
  if (Array.isArray(detail)) {
    const errors = detail
      .map((error: ValidationError) => formatValidationError(error))
      .join('\n')
    return errors || defaultMessage
  }

  // 2. 处理字符串错误
  if (typeof detail === 'string') {
    return detail
  }

  // 3. 处理对象错误
  if (typeof detail === 'object') {
    // 可能是自定义错误对象
    if ((detail as Record<string, unknown>).message) {
      return String((detail as Record<string, unknown>).message)
    }
    // 尝试 JSON 序列化
    try {
      return JSON.stringify(detail, null, 2)
    } catch {
      return defaultMessage
    }
  }

  return defaultMessage
}

/**
 * 解析并提取第一个错误信息（用于简短提示）
 */
export function parseApiErrorShort(err: unknown, defaultMessage: string = '操作失败'): string {
  const fullError = parseApiError(err, defaultMessage)

  // 如果有多行错误，只取第一行
  const lines = fullError.split('\n')
  return lines[0] || defaultMessage
}
