import { findClaimTokenByToken, getClaimTokenById, updateClaimToken } from '../../../repositories/claim-token-repo.js'
import { getOrderById } from '../../../repositories/order-repo.js'
import { getOrderItemById } from '../../../repositories/order-item-repo.js'
import { findTaskByClaimTokenId, getTaskById, updateTask } from '../../../repositories/task-repo.js'
import { releaseReservedInventoryItem } from '../../../repositories/inventory-repo.js'
import { createHttpError } from '../../../utils/http.js'
import { nowIso } from '../../../utils/time.js'
import { CLAIM_TERMINAL_STATUSES } from './shared.js'

export async function getClaimContext(token) {
  const normalized = String(token || '').trim()

  if (!normalized) {
    throw createHttpError('缺少领取 token', {
      statusCode: 400,
      errorCode: 'missing_claim_token',
    })
  }

  const claimToken = await findClaimTokenByToken(normalized)

  if (!claimToken) {
    throw createHttpError('领取链接无效或不存在', {
      statusCode: 404,
      errorCode: 'claim_token_not_found',
    })
  }

  const task = await findTaskByClaimTokenId(claimToken.id)

  if (!task) {
    throw createHttpError('领取任务不存在', {
      statusCode: 404,
      errorCode: 'claim_task_not_found',
    })
  }

  if (claimToken.status !== 'active') {
    throw createHttpError('领取链接当前不可用', {
      statusCode: 410,
      errorCode: 'claim_token_inactive',
    })
  }

  if (claimToken.expired_at && new Date(claimToken.expired_at).getTime() <= Date.now()) {
    const expiredContext = await expireClaimContext(claimToken, task)

    throw createHttpError('领取链接已过期', {
      statusCode: 410,
      errorCode: 'claim_token_expired',
      context: expiredContext,
    })
  }

  const [order, orderItem] = await Promise.all([
    getOrderById(task.order_id),
    getOrderItemById(task.order_item_id),
  ])

  if (!order || !orderItem) {
    throw createHttpError('领取任务关联订单不完整', {
      statusCode: 500,
      errorCode: 'claim_order_incomplete',
    })
  }

  return {
    claimToken,
    task,
    order,
    orderItem,
  }
}

export async function getClaimContextByTaskId(taskId) {
  const task = await getTaskById(Number(taskId))

  if (!task) {
    throw createHttpError('领取任务不存在', {
      statusCode: 404,
      errorCode: 'claim_task_not_found',
    })
  }

  const claimTokenId = Number(task.primary_claim_token_id || 0)

  if (!claimTokenId) {
    throw createHttpError('当前任务还没有领取链接', {
      statusCode: 409,
      errorCode: 'claim_token_missing',
    })
  }

  const claimToken = await getClaimTokenById(claimTokenId)

  if (!claimToken) {
    throw createHttpError('领取链接不存在', {
      statusCode: 404,
      errorCode: 'claim_token_not_found',
    })
  }

  const [order, orderItem] = await Promise.all([
    getOrderById(task.order_id),
    getOrderItemById(task.order_item_id),
  ])

  if (!order || !orderItem) {
    throw createHttpError('领取任务关联订单不完整', {
      statusCode: 500,
      errorCode: 'claim_order_incomplete',
    })
  }

  return {
    claimToken,
    task,
    order,
    orderItem,
  }
}

async function expireClaimContext(claimToken, task) {
  const now = nowIso()
  const nextClaimToken = await updateClaimToken(claimToken.id, {
    status: 'expired',
    updated_at: now,
  })

  let nextTask = task

  if (!CLAIM_TERMINAL_STATUSES.has(String(task.task_status || '')) && task.task_status !== 'redeemed') {
    if (task.primary_inventory_item_id) {
      await releaseReservedInventoryItem(task.primary_inventory_item_id, now)
    }

    nextTask = await updateTask(task.id, {
      task_status: 'expired',
      inventory_status: 'pending',
      user_action_status: 'expired',
      last_error: '领取链接已过期，预占库存项已释放',
      updated_at: now,
    })
  }

  return {
    claimToken: nextClaimToken,
    task: nextTask,
  }
}
