import type {
  GrabWorkOrderFailureReason,
  ProblemWorkOrderResolutionAction,
} from '../../repositories/worker-platform/index.js'
import { createHttpError } from '../../utils/http.js'

export function normalizeReviewStatus(value: unknown) {
  const status = String(value || '').trim()
  if (['active', 'rejected', 'disabled', 'pending_review'].includes(status)) return status
  return 'pending_review'
}

/** 冻结原因必须可追溯，限制长度避免异常大载荷写入账号资料。 */
export function normalizeWorkerFreezeReason(value: unknown): string {
  const reason = String(value || '').trim()
  if (!reason) {
    throw createHttpError('请填写冻结原因或备注', {
      statusCode: 400,
      errorCode: 'worker_freeze_reason_required',
    })
  }
  if (reason.length > 500) {
    throw createHttpError('冻结原因不能超过 500 个字符', {
      statusCode: 400,
      errorCode: 'worker_freeze_reason_too_long',
    })
  }
  return reason
}

export function normalizeProblemResolutionAction(value: unknown): ProblemWorkOrderResolutionAction {
  const action = String(value || '').trim()
  if (['return_to_worker', 'reopen', 'cancel_release', 'cancel_deduct'].includes(action)) {
    return action as ProblemWorkOrderResolutionAction
  }
  throw createHttpError('问题单处置方式不正确', {
    statusCode: 400,
    errorCode: 'work_order_problem_resolution_action_invalid',
  })
}

export function throwGrabWorkOrderFailure(failureReason: GrabWorkOrderFailureReason | null): never {
  if (failureReason === 'worker_active_order_limit') {
    throw createHttpError('已达到当前等级最大同时接单量', {
      statusCode: 409,
      errorCode: 'worker_active_order_limit',
    })
  }
  if (failureReason === 'worker_deposit_insufficient') {
    throw createHttpError('余额不足，无法冻结所需押金', {
      statusCode: 409,
      errorCode: 'worker_deposit_insufficient',
    })
  }
  throw createHttpError('抢单失败，订单可能已被抢走', {
    statusCode: 409,
    errorCode: 'work_order_grab_conflict',
  })
}

export function normalizeEnabledStatus(value: unknown) {
  return String(value || 'active').trim() === 'disabled' ? 'disabled' : 'active'
}

export function normalizeWalletLedgerType(value: unknown) {
  const ledgerType = String(value || '').trim()
  if (!ledgerType) return ''
  if (
    [
      'manual_credit',
      'withdraw_freeze',
      'withdraw_paid',
      'withdraw_release',
      'deposit_freeze',
      'deposit_release',
      'deposit_pending_unfreeze',
      'reward_pending_unfreeze',
      'deposit_unfreeze',
      'deposit_deduction',
      'reward_settlement',
      'sharing_reward',
      'after_sales_deposit_deduction',
      'after_sales_balance_deduction',
      'after_sales_debt_offset',
      'after_sales_refund',
    ].includes(ledgerType)
  ) {
    return ledgerType
  }
  throw createHttpError('钱包流水类型不正确', {
    statusCode: 400,
    errorCode: 'worker_wallet_ledger_type_invalid',
  })
}

export function normalizeFinanceRequestType(value: unknown) {
  const requestType = String(value || '').trim()
  if (!requestType) return ''
  if (['recharge', 'withdraw'].includes(requestType)) return requestType
  throw createHttpError('资金申请类型不正确', {
    statusCode: 400,
    errorCode: 'worker_finance_request_type_invalid',
  })
}

export function normalizeFinanceRequestStatus(value: unknown) {
  const status = String(value || '').trim()
  if (!status) return ''
  if (['pending', 'approved', 'rejected', 'cancelled'].includes(status)) return status
  throw createHttpError('资金申请状态不正确', {
    statusCode: 400,
    errorCode: 'worker_finance_request_status_invalid',
  })
}

export function normalizeAdminFinanceReviewStatus(value: unknown) {
  const status = String(value || '').trim()
  if (['approved', 'rejected', 'cancelled'].includes(status)) return status
  throw createHttpError('审核状态不正确', {
    statusCode: 400,
    errorCode: 'worker_finance_review_status_invalid',
  })
}

export function normalizeWithdrawChannel(value: unknown) {
  const channel = String(value || '').trim()
  if (['alipay', 'wechat'].includes(channel)) return channel
  throw createHttpError('提现方式不正确', {
    statusCode: 400,
    errorCode: 'worker_withdraw_channel_invalid',
  })
}

/** 提现金额超过 100 元时，仅允许使用支付宝。 */
export function assertWithdrawChannelAllowedForAmount(amount: number, channel: string) {
  if (amount > 10_000 && channel !== 'alipay') {
    throw createHttpError('提现金额超过 100 元时，仅支持支付宝提现', {
      statusCode: 400,
      errorCode: 'worker_withdraw_channel_amount_limited',
    })
  }
}

export function normalizeMatchType(value: unknown) {
  return String(value || '').trim() === 'exact' ? 'exact' : 'contains'
}

export function normalizeSlugKey(value: unknown, fallback: string) {
  const key = String(value || '')
    .trim()
    .toLowerCase()
    .replace(/[^a-z0-9._-]+/g, '-')
    .replace(/^-+|-+$/g, '')
  return key || fallback
}

export function normalizeUsername(value: unknown): string {
  return String(value || '')
    .trim()
    .toLowerCase()
}

export function normalizePassword(value: unknown): string {
  return String(value || '').trim()
}

export function validateWorkerUsername(username: string) {
  if (!/^[a-zA-Z0-9._-]{3,32}$/.test(username)) {
    throw createHttpError('接单账号格式无效，需为 3-32 位字母数字或 ._-', {
      statusCode: 400,
      errorCode: 'worker_username_invalid',
    })
  }
}

export function validateWorkerPassword(password: string) {
  if (!isWorkerPasswordStrong(password)) {
    throw createHttpError('接单密码至少 8 位，且必须包含英文字母和数字', {
      statusCode: 400,
      errorCode: 'worker_password_invalid',
    })
  }
}

export function isWorkerPasswordStrong(password: string): boolean {
  return password.length >= 8 && /[a-zA-Z]/.test(password) && /\d/.test(password)
}

export function normalizeOptionalId(value: unknown): number | null {
  const parsed = Number(value)
  return Number.isInteger(parsed) && parsed > 0 ? parsed : null
}

export function normalizeAmountFen(value: unknown, fallback: number): number {
  const text = String(value ?? '').trim()
  if (!text) return fallback
  const parsed = Number(text)
  if (!Number.isFinite(parsed) || parsed < 0) return fallback
  return Math.round(parsed * 100)
}

export function normalizeProofFiles(value: unknown): Array<Record<string, unknown>> {
  if (!Array.isArray(value)) return []
  const files: Array<Record<string, unknown>> = []
  for (const item of value) {
    if (!item || typeof item !== 'object') continue
    const file = item as Record<string, unknown>
    const url = String(file.url || '').trim()
    if (!url) continue
    files.push({
      url,
      thumbnailUrl: String(file.thumbnailUrl || file.thumbnail_url || '').trim(),
      mediumUrl: String(file.mediumUrl || file.medium_url || '').trim(),
      objectKey: String(file.objectKey || file.object_key || '').trim(),
      originalFilename: String(
        file.originalFilename || file.original_filename || file.name || '',
      ).trim(),
      contentType: String(file.contentType || file.content_type || '').trim(),
      sizeBytes: Number(file.sizeBytes || file.size_bytes || 0),
    })
    if (files.length >= 10) break
  }
  return files
}
