// Business logic for the moderation dashboard: reshapes the raw mod_actions
// reads into the shapes the admin UI consumes, and annotates each action with
// whether it was an automated (bot) action. For a Discord bot the application_id
// IS the bot's user id, and the filter/spam pipeline records automated actions
// with staff_user_id = the bot user (see bot/src/discord/messageFilter.js), so
// staff_user_id === bot_config.application_id reliably flags automated actions
// without needing new columns on mod_actions.
const moderationDb = require('./moderation.db')
const botConfigDb = require('../botConfig/botConfig.db')
const { zeroCounts, annotate, reshapeWindows, windowValue } = require('./moderation.pure')

const DAY_MS = 24 * 60 * 60 * 1000
const WINDOW_KEYS = ['24h', '7d', '30d']

async function botApplicationId() {
  try {
    const cfg = await botConfigDb.get()
    return cfg ? cfg.application_id : null
  } catch {
    return null
  }
}

// Counts by type across 24h / 7d / 30d windows for the overview tiles. Covers
// moderation actions (mod_actions) plus the Phase 6b event streams: member
// joins/leaves, attributed invite joins, and filter/spam hits.
async function summary() {
  const now = Date.now()
  const cutoffs = {
    cutoff24h: new Date(now - DAY_MS),
    cutoff7d: new Date(now - 7 * DAY_MS),
    cutoff30d: new Date(now - 30 * DAY_MS),
  }

  const [modRows, memberRows, inviteRow, filterRow, spamRow] = await Promise.all([
    moderationDb.countsByWindow(cutoffs),
    moderationDb.memberCountsByWindow(cutoffs),
    moderationDb.inviteJoinCountsByWindow(cutoffs),
    moderationDb.tableCountsByWindow('filter_hits', cutoffs),
    moderationDb.tableCountsByWindow('spam_hits', cutoffs),
  ])

  const windows = reshapeWindows(modRows).windows
  const joinRow = memberRows.find((r) => r.event_type === 'join')
  const leaveRow = memberRows.find((r) => r.event_type === 'leave')
  for (const w of WINDOW_KEYS) {
    windows[w].joins = windowValue(joinRow, w)
    windows[w].leaves = windowValue(leaveRow, w)
    windows[w].invite_joins = windowValue(inviteRow, w)
    windows[w].filter_hits = windowValue(filterRow, w)
    windows[w].spam_hits = windowValue(spamRow, w)
  }
  return { windows }
}

// Recent event feeds for the overview's secondary panel (Phase 6b).
async function members(opts) {
  return moderationDb.recentMemberEvents(opts)
}
async function filterHits(opts) {
  return moderationDb.recentFilterHits(opts)
}
async function spamHits(opts) {
  return moderationDb.recentSpamHits(opts)
}

async function recent(opts) {
  const appId = await botApplicationId()
  return annotate(await moderationDb.recentActions(opts), appId)
}

async function userActions(discordId, opts) {
  const appId = await botApplicationId()
  return annotate(await moderationDb.userActions(discordId, opts), appId)
}

// Header data for the per-user history page: latest known tag, linked site
// account (if any), and all-time counts per action type.
async function userSummary(discordId) {
  const [countRows, tag, linked] = await Promise.all([
    moderationDb.userCounts(discordId),
    moderationDb.latestTag(discordId),
    moderationDb.linkedAccount(discordId),
  ])
  const counts = zeroCounts()
  let total = 0
  for (const row of countRows) {
    const c = Number(row.c) || 0
    if (counts[row.action_type] !== undefined) counts[row.action_type] = c
    total += c
  }
  return {
    discord_user_id: discordId,
    tag,
    linked_account: linked,
    counts,
    total_actions: total,
  }
}

async function search(term, opts) {
  return moderationDb.searchTargets(term, opts)
}

module.exports = { summary, recent, userActions, userSummary, search, members, filterHits, spamHits }
