import { createHttpError } from '../../utils/http.js'
import { assertOpen91Config } from './config.js'
import type { JsonObject } from '../../types/json.js'

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

export function normalizeOpen91CreatePayload(payload: JsonObject = {}) {
  return {
    orderNo: normalizeOpen91String(payload.orderNo),
    productNo: normalizeOpen91String(payload.productNo),
    buyNum: normalizeOpen91BuyNum(payload.buyNum),
    maxAmount: normalizeOpen91OptionalAmount(payload.maxAmount),
    callbackUrl: normalizeOpen91String(payload.callbackUrl),
    timestamp: normalizeOpen91Timestamp(payload.timestamp),
    version: normalizeOpen91String(payload.version),
    sign: normalizeOpen91String(payload.sign).toUpperCase(),
  }
}

export function normalizeOpen91QueryPayload(payload: JsonObject = {}) {
  return {
    orderNo: normalizeOpen91String(payload.orderNo),
    timestamp: normalizeOpen91Timestamp(payload.timestamp),
    version: normalizeOpen91String(payload.version),
    sign: normalizeOpen91String(payload.sign).toUpperCase(),
  }
}

export function assertOpen91CreatePayload(payload: JsonObject, config = assertOpen91Config()) {
  if (!payload.orderNo) {
    throw createHttpError('缺少 orderNo', {
      statusCode: 400,
      errorCode: 'open91_missing_order_no',
    })
  }

  if (!payload.productNo) {
    throw createHttpError('缺少 productNo', {
      statusCode: 400,
      errorCode: 'open91_missing_product_no',
    })
  }

  if (!Number.isInteger(payload.buyNum) || payload.buyNum <= 0) {
    throw createHttpError('buyNum 必须是大于 0 的整数', {
      statusCode: 400,
      errorCode: 'open91_invalid_buy_num',
    })
  }

  assertOpen91CommonPayload(payload, config)
}

export function assertOpen91QueryPayload(payload: JsonObject, config = assertOpen91Config()) {
  if (!payload.orderNo) {
    throw createHttpError('缺少 orderNo', {
      statusCode: 400,
      errorCode: 'open91_missing_order_no',
    })
  }

  assertOpen91CommonPayload(payload, config)
}

export function assertOpen91Timestamp(
  timestamp: unknown,
  toleranceSeconds = assertOpen91Config().timestampToleranceSeconds,
) {
  const nowSeconds = Math.floor(Date.now() / 1000)
  if (Math.abs(nowSeconds - Number(timestamp)) > Math.max(1, Number(toleranceSeconds) || 600)) {
    throw createHttpError('timestamp 已过期', {
      statusCode: 400,
      errorCode: 'open91_expired_timestamp',
    })
  }
}

function assertOpen91CommonPayload(payload: JsonObject, config: JsonObject) {
  if (!payload.timestamp) {
    throw createHttpError('缺少 timestamp', {
      statusCode: 400,
      errorCode: 'open91_missing_timestamp',
    })
  }

  if (!payload.version) {
    throw createHttpError('缺少 version', {
      statusCode: 400,
      errorCode: 'open91_missing_version',
    })
  }

  if (payload.version !== config.version) {
    throw createHttpError(`version 不匹配，当前仅支持 ${config.version}`, {
      statusCode: 400,
      errorCode: 'open91_invalid_version',
    })
  }

  if (!payload.sign) {
    throw createHttpError('缺少 sign', {
      statusCode: 400,
      errorCode: 'open91_missing_sign',
    })
  }
}

function normalizeOpen91BuyNum(value: unknown) {
  const parsed = Number(value)
  return Number.isInteger(parsed) ? parsed : 0
}

function normalizeOpen91OptionalAmount(value: unknown) {
  const normalized = normalizeOpen91String(value)
  if (!normalized) {
    return ''
  }

  if (!/^\d+(?:\.\d+)?$/.test(normalized)) {
    throw createHttpError('maxAmount 格式无效', {
      statusCode: 400,
      errorCode: 'open91_invalid_max_amount',
    })
  }

  return normalized
}

function normalizeOpen91Timestamp(value: unknown) {
  const normalized = normalizeOpen91String(value)
  if (!/^\d{10}$/.test(normalized)) {
    return 0
  }

  return Number(normalized)
}
