import { getTaskById, updateTask } from '../../../repositories/task-repo.js'
import { findKuaishouIndustryVoucherByCode } from '../../../repositories/kuaishou-industry-voucher-repo.js'
import { normalizeTimestampIso } from '../../../utils/time.js'
import { logWarn } from '../../../utils/logger.js'
import { TASK_STATUS } from '../../../domain/task-status.js'
import type { JsonObject } from '../../../types/json.js'
import { getKuaishouIndustryConfig, assertMatchingAppKey } from './config.js'
import { normalizeConsumeCodePayload, assertConsumeCodePayload } from './payload.js'
import { assertKuaishouIndustrySignature } from './crypto.js'
import { buildIndustrySuccessResponse, buildIndustryErrorResponse } from './response.js'
import { consumeCallback } from './consume-callback-service.js'
import { consumeKuaishouIndustryVoucher } from './voucher-service.js'
import { attachKuaishouIndustryVoucherToTask } from './voucher-binding-service.js'

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

  assertKuaishouIndustrySignature(rawBody, config)

  const params = normalizeConsumeCodePayload(rawBody)
  assertConsumeCodePayload(params, config)
  assertMatchingAppKey(params.appKey)

  const now = normalizeTimestampIso(new Date().toISOString())
  const normalizedOid = params.oid

  let consumedCount = 0
  let callbackSellerId = params.sellerId

  for (const eticket of params.etickets) {
    const voucher = await findKuaishouIndustryVoucherByCode(String(eticket.id || ''), normalizedOid)
    if (!voucher) {
      continue
    }
    if (!callbackSellerId) {
      callbackSellerId = String(voucher.seller_id || '').trim()
    }

    const task = voucher.task_id ? await getTaskById(voucher.task_id) : null
    const consumed = await consumeKuaishouIndustryVoucher(voucher, {
      source: 'kuaishou_industry_consume_code',
      token: params.token,
      consumeType: params.consumeType,
      consumeTime: params.consumeTime || Date.now(),
      storeName: params.storeName,
      storeAddress: params.storeAddress,
      expressCode: params.expressCode,
      expressNo: params.expressNo,
      serialNum: params.seriallNum,
      skipCallback: true,
      ...(task ? { task } : {}),
    })

    if (!consumed.ok || !consumed.voucher) {
      continue
    }

    if (task) {
      const taskStatus = String(task.task_status || '')
      const isDispatched = taskStatus === TASK_STATUS.DISPATCHED_PENDING_RETURN
      const updatedTask = await updateTask(task.id, {
        task_status: isDispatched ? TASK_STATUS.COMPLETED : taskStatus,
        delivery_status: isDispatched ? 'delivered' : task.delivery_status,
        result_code: params.status,
        result_message: `电子凭证核销方式: ${params.consumeType}`,
        redeemed_at: isDispatched ? now : task.redeemed_at,
        updated_at: now,
      })

      if (updatedTask) {
        await attachKuaishouIndustryVoucherToTask(updatedTask, consumed.voucher, {
          source: 'kuaishou_industry_consume_code',
          now,
        })
      }
    }

    consumedCount++
  }

  if (consumedCount === 0) {
    return buildIndustryErrorResponse(
      4012005,
      `未找到匹配的卡券: ${params.etickets.map((e) => e.id).join(',')}`,
    )
  }

  fireConsumeCallback({
    oid: normalizedOid,
    sellerId: callbackSellerId,
    etickets: params.etickets.map((e) => ({
      id: String(e.id),
      code: e.code,
      num: Number(e.num) || 1,
      goodsValue: e.goodsValue,
    })),
    status: params.status,
    consumeType: params.consumeType,
    consumeTime: params.consumeTime,
    storeName: params.storeName,
    storeAddress: params.storeAddress,
    expressNo: params.expressNo,
    expressCode: params.expressCode,
    appointmentTime: params.appointmentTime,
    ext: params.ext,
    token: params.token,
    seriallNum: params.seriallNum,
    consumePoiId: params.consumePoiId,
  })

  return buildIndustrySuccessResponse({
    oid: normalizedOid,
    consumedCount,
  })
}

function fireConsumeCallback(input: Parameters<typeof consumeCallback>[0]) {
  consumeCallback(input).catch((err) => {
    logWarn('[kuaishou-industry/consume-code]', '核销回调异步执行异常', {
      oid: input.oid,
      error: err instanceof Error ? err.message : String(err),
    })
  })
}
