const prisma = require("./client");

async function voteDealTxWithDb(db, { dealId, userId, voteType, createdAt }) {
  const timestamp = createdAt instanceof Date ? createdAt : createdAt ? new Date(createdAt) : new Date()
  const current = await db.dealVote.findUnique({
    where: { dealId_userId: { dealId, userId } },
    select: { voteType: true },
  })

  const oldValue = current ? current.voteType : 0
  const delta = voteType - oldValue

  // history (append-only)
  await db.dealVoteHistory.create({
    data: { dealId, userId, voteType, createdAt: timestamp },
  })

  // current state
  await db.dealVote.upsert({
    where: { dealId_userId: { dealId, userId } },
    create: {
      dealId,
      userId,
      voteType,
      createdAt: timestamp,
      lastVotedAt: timestamp,
    },
    update: {
      voteType,
      lastVotedAt: timestamp,
    },
  })

  // score delta
  if (delta !== 0) {
    await db.deal.update({
      where: { id: dealId },
      data: { score: { increment: delta } },
    })
  }

  const deal = await db.deal.findUnique({
    where: { id: dealId },
    select: { score: true },
  })

  return {
    dealId,
    voteType,
    delta,
    score: deal?.score ?? null,
  }
}

async function voteDealTx({ dealId, userId, voteType, createdAt }) {
  return prisma.$transaction((db) =>
    voteDealTxWithDb(db, { dealId, userId, voteType, createdAt })
  )
}

async function voteDealBatchTx(items = []) {
  if (!items.length) return { count: 0 }
  return prisma.$transaction(async (db) => {
    for (const item of items) {
      await voteDealTxWithDb(db, item)
    }
    return { count: items.length }
  })
}

module.exports = {
  voteDealTx,
  voteDealBatchTx,
};
