import type { JsonObject } from '../../../types/json.js'
import {
  findKuaishouIndustryVoucherByCode,
  listKuaishouIndustryVouchersByOid,
} from '../../../repositories/kuaishou-industry-voucher-repo.js'
import { getKuaishouIndustryConfig, assertMatchingAppKey } from './config.js'
import { normalizeQueryCodePayload, assertQueryCodePayload } from './payload.js'
import { assertKuaishouIndustrySignature } from './crypto.js'
import {
  buildIndustrySuccessResponse,
  buildIndustryErrorResponse,
  buildIndustryQueryCodeData,
} from './response.js'
import {
  buildKuaishouIndustryEticketFromVoucher,
  isKuaishouIndustryVoucherSendCallbackSuccess,
} from './voucher-service.js'

export async function handleQueryCode(rawBody: JsonObject = {}) {
  const config = getKuaishouIndustryConfig()

  assertKuaishouIndustrySignature(rawBody, config)

  const params = normalizeQueryCodePayload(rawBody)
  assertQueryCodePayload(params, config)
  assertMatchingAppKey(params.appKey)

  const normalizedOid = params.oid

  if (params.eticketId) {
    const matched = await findKuaishouIndustryVoucherByCode(params.eticketId, normalizedOid)
    if (!matched) {
      return buildIndustryErrorResponse(4012005, `卡券不存在: ${params.eticketId}`)
    }
    if (!isKuaishouIndustryVoucherSendCallbackSuccess(matched)) {
      return buildIndustryErrorResponse(4012005, `卡券尚未完成发码: ${params.eticketId}`)
    }

    const eticket = buildKuaishouIndustryEticketFromVoucher(matched, params.eticketType)
    return buildIndustrySuccessResponse(
      buildIndustryQueryCodeData({
        oid: normalizedOid,
        sendType: params.sendType,
        sendNum: 1,
        etickets: [eticket],
      }),
    )
  }

  const vouchers = (await listKuaishouIndustryVouchersByOid(normalizedOid)).filter(
    isKuaishouIndustryVoucherSendCallbackSuccess,
  )
  if (vouchers.length === 0) {
    return buildIndustryErrorResponse(4012002, `订单不存在: ${normalizedOid}`)
  }

  const etickets = vouchers.map((voucher) =>
    buildKuaishouIndustryEticketFromVoucher(voucher, params.eticketType),
  )

  return buildIndustrySuccessResponse(
    buildIndustryQueryCodeData({
      oid: normalizedOid,
      sendType: params.sendType,
      sendNum: etickets.reduce((sum, e) => sum + (Number(e.num) || 0), 0),
      etickets,
    }),
  )
}
