import { createHttpError } from '../../../utils/http.js'
import type { JsonObject } from './domain.js'

/**
 * 将 cloudtentacles 上游错误包装成可运维定位的文案。
 * 避免只回「权限不足」让人误判成后台角色权限。
 */
export function wrapCloudtentaclesOperationError(
  error: unknown,
  operation: {
    action: string
    actionLabel: string
    sourceKey?: unknown
    vnKey?: unknown
    vnId?: unknown
    vnPhone?: unknown
  },
) {
  const upstreamMessage = resolveErrorMessage(error)
  const upstreamCode =
    resolveErrorField(error, 'errorCode') ||
    resolveUpstreamCode(error) ||
    'cloudtentacles_operation_failed'
  const sourceKey = String(operation.sourceKey || '').trim() || 'unknown'
  const vnKey = String(operation.vnKey || '').trim()
  const vnId = Number(operation.vnId || 0) || 0
  const vnPhone = String(operation.vnPhone || '').trim()

  const parts = [
    `cloudtentacles ${operation.actionLabel}失败`,
    upstreamMessage ? `上游：${upstreamMessage}` : '',
    `账号=${sourceKey}`,
    vnId > 0 ? `vnId=${vnId}` : '',
    vnKey ? `vnKey=${vnKey}` : '',
    vnPhone ? `phone=${vnPhone}` : '',
    '请到「平台配置-cloudtentacles」校验该账号登录态；若账号与取号时不一致会导致退号/取链权限不足',
  ].filter(Boolean)

  const statusCode = resolveStatusCode(error)
  // 业务失败不要用 401，避免前端当成后台未登录/无权限
  const normalizedStatus =
    statusCode === 401 || statusCode === 403 ? 409 : statusCode >= 400 ? statusCode : 409

  return createHttpError(parts.join('；'), {
    statusCode: normalizedStatus,
    errorCode: String(upstreamCode || `cloudtentacles_${operation.action}_failed`).trim(),
    cause: error instanceof Error ? error : undefined,
    context: {
      cloudtentacles: {
        action: operation.action,
        actionLabel: operation.actionLabel,
        sourceKey,
        vnKey,
        vnId,
        vnPhone,
        upstreamMessage,
        upstreamCode: resolveUpstreamCode(error),
        upstreamPayload: resolveUpstreamPayload(error),
      },
    },
  })
}

export function isCloudtentaclesPermissionLikeError(error: unknown): boolean {
  const message = resolveErrorMessage(error)
  const code = resolveUpstreamCode(error)
  return (
    message.includes('权限不足') ||
    message.includes('没有权限') ||
    message.includes('无权限') ||
    String(code) === '-1'
  )
}

function resolveErrorMessage(error: unknown) {
  if (error instanceof Error && error.message) {
    return error.message.trim()
  }
  return String(error || '未知错误').trim()
}

function resolveErrorField(error: unknown, field: string) {
  if (!error || typeof error !== 'object') {
    return ''
  }
  return String((error as JsonObject)[field] || '').trim()
}

function resolveStatusCode(error: unknown) {
  if (!error || typeof error !== 'object') {
    return 409
  }
  const statusCode = Number((error as JsonObject).statusCode || 0)
  return Number.isFinite(statusCode) && statusCode > 0 ? statusCode : 409
}

function resolveUpstreamCode(error: unknown) {
  if (!error || typeof error !== 'object') {
    return ''
  }
  const context = (error as { context?: unknown }).context
  if (!context || typeof context !== 'object') {
    return ''
  }
  return String((context as JsonObject).upstreamCode ?? '').trim()
}

function resolveUpstreamPayload(error: unknown) {
  if (!error || typeof error !== 'object') {
    return null
  }
  const context = (error as { context?: unknown }).context
  if (!context || typeof context !== 'object') {
    return null
  }
  return (context as JsonObject).upstreamPayload ?? null
}
