import { updateTask } from '../../../repositories/task-repo.js'
import type { JsonObject } from '../../../types/json.js'
import {
  listKuaishouIndustryVouchersByOid,
  updateKuaishouIndustryVoucherByCode,
} 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 { getKuaishouIndustryConfig, assertMatchingAppKey } from './config.js'
import { normalizeDestroyCodePayload, assertDestroyCodePayload } from './payload.js'
import { assertKuaishouIndustrySignature } from './crypto.js'
import { buildIndustrySuccessResponse } from './response.js'
import { destroyCallback } from './destroy-callback-service.js'
import { attachKuaishouIndustryVoucherToTask } from './voucher-binding-service.js'
import { resolveKuaishouIndustryEticketType } from './voucher-service.js'

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

  assertKuaishouIndustrySignature(rawBody, config)

  const params = normalizeDestroyCodePayload(rawBody)
  assertDestroyCodePayload(params, config)
  assertMatchingAppKey(params.appKey)

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

  const vouchers = await listKuaishouIndustryVouchersByOid(normalizedOid)
  const targetIds = new Set(params.etickets.map((e) => String(e.id || '').trim()).filter(Boolean))
  const targetVouchers =
    targetIds.size > 0
      ? vouchers.filter((voucher) => targetIds.has(String(voucher.voucher_code || '').trim()))
      : vouchers
  const callbackSellerId =
    params.sellerId ||
    String(
      targetVouchers.find((voucher) => String(voucher.seller_id || '').trim())?.seller_id || '',
    ).trim()
  const callbackToken = params.token || resolveDestroyCallbackToken(targetVouchers)
  const eticketType = resolveKuaishouIndustryEticketType(targetVouchers[0] || null)

  for (const voucher of targetVouchers) {
    const status = String(voucher.status || '')
      .trim()
      .toUpperCase()
    if (status === 'CONSUMED') {
      continue
    }

    const updatedVoucher = await updateKuaishouIndustryVoucherByCode(voucher.voucher_code, {
      status: 'DESTROYED',
      destroyedAt: now,
      updatedAt: now,
    })

    if (voucher.task_id) {
      const updatedTask = await updateTask(voucher.task_id, {
        task_status: TASK_STATUS.CLOSED,
        delivery_status: 'cancelled',
        result_code: params.reason,
        result_message: `电子凭证销毁: ${params.reason}`,
        updated_at: now,
      })

      if (updatedTask && updatedVoucher) {
        await attachKuaishouIndustryVoucherToTask(updatedTask, updatedVoucher, {
          source: 'kuaishou_industry_destroy_code',
          now,
        })
      }
    }
  }

  fireDestroyCallback({
    oid: normalizedOid,
    sellerId: callbackSellerId,
    etickets: params.etickets.map((e) => ({
      id: String(e.id),
      code: e.code,
      num: Number(e.num) || 1,
      goodsValue: e.goodsValue,
    })),
    reason: params.reason,
    token: callbackToken,
    ...(eticketType ? { eticketType } : {}),
  })

  return buildIndustrySuccessResponse({ oid: normalizedOid })
}

export function resolveDestroyCallbackToken(vouchers: Array<{ token?: unknown }> = []) {
  return String(vouchers.find((voucher) => String(voucher.token || '').trim())?.token || '').trim()
}

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