// Business layer for moderation appeals (Phase 6c). A thin wrapper over
// appeals.db that returns the freshly-read row after each mutation, so callers
// always hand the client the enriched (joined) shape rather than a bare
// insert/update result. Ownership/type/duplicate validation lives in the
// controllers (they hold the request context — caller identity, the mod_action
// being appealed); this layer just performs the persistence.
const appealsDb = require('./appeals.db')

async function submit({ modActionId, discordUserId, actionType, userId, submittedText }) {
  const id = await appealsDb.insert({ modActionId, discordUserId, actionType, userId, submittedText })
  return appealsDb.getById(id)
}

async function getById(id) {
  return appealsDb.getById(id)
}

// The caller's own appeals, newest first.
async function listMine(userId) {
  return appealsDb.listForUser(userId)
}

// The caller's appealable actions (ban/mute with no active appeal).
async function eligibleActions(discordUserId) {
  return appealsDb.eligibleActions(discordUserId)
}

// The active (pending/under_review) appeal for an action, or null.
async function activeForAction(modActionId) {
  return appealsDb.activeForAction(modActionId)
}

// Owner-initiated withdraw: flip to 'withdrawn' and return the updated row.
async function withdraw(id) {
  await appealsDb.setStatus(id, 'withdrawn')
  return appealsDb.getById(id)
}

// Staff queue read.
async function queue({ statuses, limit, offset }) {
  return appealsDb.listQueue({ statuses, limit, offset })
}

// Staff claim: pending -> under_review, stamping the handler.
async function claim(id, { handlerUserId, handlerTag }) {
  await appealsDb.setUnderReview(id, { handlerUserId, handlerTag })
  return appealsDb.getById(id)
}

// Staff resolution (approved/denied) with the reversal outcome already decided
// by the controller (which owns the best-effort bot call).
async function resolve(id, opts) {
  await appealsDb.resolve(id, opts)
  return appealsDb.getById(id)
}

// Appeals for a Discord id (admin per-user view).
async function listForDiscordUser(discordUserId) {
  return appealsDb.listForDiscordUser(discordUserId)
}

// Number of appeals still awaiting first triage (status = 'pending'), for the
// dashboard badge.
async function pendingCount() {
  const rows = await appealsDb.countByStatus()
  const row = rows.find((r) => r.status === 'pending')
  return row ? Number(row.c) : 0
}

module.exports = {
  submit,
  getById,
  listMine,
  eligibleActions,
  activeForAction,
  withdraw,
  queue,
  claim,
  resolve,
  listForDiscordUser,
  pendingCount,
}
