const prisma = require("./client")

function getDb(db) {
  return db || prisma
}

async function findDeals(where = {}, options = {}, db) {
  const p = getDb(db)
  return p.deal.findMany({
    where,
    include: options.include || undefined,
    select: options.select || undefined,
    orderBy: options.orderBy || { createdAt: "desc" },
    skip: options.skip || 0,
    take: options.take || undefined,
  })
}

async function findSimilarCandidates(where, options = {}, db) {
  const p = getDb(db)
  const safeTake = Math.min(Math.max(Number(options.take) || 30, 1), 200)

  return p.deal.findMany({
    where,
    orderBy: options.orderBy || [{ score: "desc" }, { createdAt: "desc" }],
    take: safeTake,
    include: options.include || undefined,
    select: options.select || undefined,
  })
}

async function findDeal(where, options = {}, db) {
  const p = getDb(db)
  return p.deal.findUnique({
    where,
    include: options.include || undefined,
    select: options.select || undefined,
  })
}

async function createDeal(data, options = {}, db) {
  const p = getDb(db)
  return p.deal.create({
    data,
    include: options.include || undefined,
    select: options.select || undefined,
  })
}

async function updateDeal(where, data, options = {}, db) {
  const p = getDb(db)
  return p.deal.update({
    where,
    data,
    include: options.include || undefined,
    select: options.select || undefined,
  })
}

async function countDeals(where = {}, db) {
  const p = getDb(db)
  return p.deal.count({ where })
}

async function findVotes(where = {}, options = {}, db) {
  const p = getDb(db)
  return p.dealVote.findMany({
    where,
    include: options.include || undefined,
    select: options.select || undefined,
  })
}

async function createVote(data, options = {}, db) {
  const p = getDb(db)
  return p.dealVote.create({
    data,
    include: options.include || undefined,
    select: options.select || undefined,
  })
}

async function updateVote(where, data, options = {}, db) {
  const p = getDb(db)
  return p.dealVote.update({
    where,
    data,
    include: options.include || undefined,
    select: options.select || undefined,
  })
}

async function countVotes(where = {}, db) {
  const p = getDb(db)
  return p.dealVote.count({ where })
}

async function aggregateDeals(where = {}, db) {
  const p = getDb(db)
  return p.deal.aggregate({
    where,
    _count: { _all: true },
    _sum: { score: true },
  })
}

module.exports = {
  findDeals,
  findSimilarCandidates,
  findDeal,
  createDeal,
  updateDeal,
  countDeals,
  findVotes,
  createVote,
  updateVote,
  countVotes,
  aggregateDeals,
}
