// Read-only access to the bot-owned moderation tables (mod_actions) for the
// admin moderation dashboard (Phase 6). These tables are normally owned by the
// bot process (bot/src/db.js) — see the comment in db/schema.sql — but they live
// in the same physical database, so the site reads them directly through the
// shared pool rather than round-tripping the bot over the internal API. This
// module NEVER writes them; all writes still belong to the bot.
//
// mod_actions is the single source of truth for ban/kick/mute/warn (every warn
// command also mirrors into `warnings`, so counting mod_actions avoids double
// counting). Accounts are correlated to Discord ids via user_identities
// (provider='discord', subject=<snowflake>), the same link the SSO flow writes.
const { query } = require('../../utils/db')

const TYPES = ['ban', 'kick', 'mute', 'warn']

// Per-type counts across three nested windows in a single scan. Boolean
// comparisons yield 1/0 in MariaDB, so SUM(created_at >= cutoff) counts the
// rows inside each window. Returns raw rows: [{ action_type, d1, d7, d30 }].
async function countsByWindow({ cutoff24h, cutoff7d, cutoff30d }) {
  return query(
    `SELECT action_type,
            SUM(created_at >= ?) AS d1,
            SUM(created_at >= ?) AS d7,
            SUM(created_at >= ?) AS d30
       FROM mod_actions
      WHERE created_at >= ?
      GROUP BY action_type`,
    [cutoff24h, cutoff7d, cutoff30d, cutoff30d],
  )
}

const ACTION_SELECT = `
  SELECT ma.id, ma.guild_id, ma.action_type,
         ma.target_user_id, ma.target_tag,
         ma.staff_user_id, ma.staff_tag,
         ma.reason, ma.duration_seconds, ma.created_at,
         ui.user_id AS target_site_user_id,
         u.username AS target_site_username
    FROM mod_actions ma
    LEFT JOIN user_identities ui
      ON ui.provider = 'discord' AND ui.subject = ma.target_user_id
    LEFT JOIN users u ON u.id = ui.user_id`

// Most-recent-first action feed, optionally filtered by type. limit/offset
// pagination matching the activity-log convention.
async function recentActions({ type = null, limit = 50, offset = 0 } = {}) {
  const where = type ? 'WHERE ma.action_type = ?' : ''
  const params = type ? [type, limit, offset] : [limit, offset]
  return query(`${ACTION_SELECT} ${where} ORDER BY ma.id DESC LIMIT ? OFFSET ?`, params)
}

// Full action history for one Discord user, optionally filtered by type.
async function userActions(discordId, { type = null, limit = 50, offset = 0 } = {}) {
  const where = type
    ? 'WHERE ma.target_user_id = ? AND ma.action_type = ?'
    : 'WHERE ma.target_user_id = ?'
  const params = type ? [discordId, type, limit, offset] : [discordId, limit, offset]
  return query(`${ACTION_SELECT} ${where} ORDER BY ma.id DESC LIMIT ? OFFSET ?`, params)
}

// All-time per-type counts for one user.
async function userCounts(discordId) {
  return query(
    `SELECT action_type, COUNT(*) AS c FROM mod_actions
      WHERE target_user_id = ? GROUP BY action_type`,
    [discordId],
  )
}

// Latest username snapshot the bot recorded for this Discord id (usernames drift).
async function latestTag(discordId) {
  const rows = await query(
    'SELECT target_tag FROM mod_actions WHERE target_user_id = ? ORDER BY id DESC LIMIT 1',
    [discordId],
  )
  return rows[0] ? rows[0].target_tag : null
}

// Linked site account for a Discord id, if any (via user_identities).
async function linkedAccount(discordId) {
  const rows = await query(
    `SELECT u.id, u.username, u.role
       FROM user_identities ui
       JOIN users u ON u.id = ui.user_id
      WHERE ui.provider = 'discord' AND ui.subject = ?
      LIMIT 1`,
    [discordId],
  )
  return rows[0] || null
}

// ── Phase 6b: member events + filter/spam hits (bot-owned, read-only) ──

// Join/leave counts per window (grouped by event_type).
async function memberCountsByWindow({ cutoff24h, cutoff7d, cutoff30d }) {
  return query(
    `SELECT event_type,
            SUM(created_at >= ?) AS d1,
            SUM(created_at >= ?) AS d7,
            SUM(created_at >= ?) AS d30
       FROM member_events
      WHERE created_at >= ?
      GROUP BY event_type`,
    [cutoff24h, cutoff7d, cutoff30d, cutoff30d],
  )
}

// Attributed-invite join counts per window (joins whose invite we identified).
async function inviteJoinCountsByWindow({ cutoff24h, cutoff7d, cutoff30d }) {
  const rows = await query(
    `SELECT SUM(created_at >= ?) AS d1, SUM(created_at >= ?) AS d7, SUM(created_at >= ?) AS d30
       FROM member_events
      WHERE event_type = 'join' AND invite_code IS NOT NULL AND created_at >= ?`,
    [cutoff24h, cutoff7d, cutoff30d, cutoff30d],
  )
  return rows[0]
}

// Row-count per window for a simple event table. `table` is an internal literal
// ('filter_hits' | 'spam_hits'), never user input — see the caller allowlist.
async function tableCountsByWindow(table, { cutoff24h, cutoff7d, cutoff30d }) {
  const rows = await query(
    `SELECT SUM(created_at >= ?) AS d1, SUM(created_at >= ?) AS d7, SUM(created_at >= ?) AS d30
       FROM ${table} WHERE created_at >= ?`,
    [cutoff24h, cutoff7d, cutoff30d, cutoff30d],
  )
  return rows[0]
}

async function recentMemberEvents({ type = null, limit = 50, offset = 0 } = {}) {
  const where = type ? 'WHERE event_type = ?' : ''
  const params = type ? [type, limit, offset] : [limit, offset]
  return query(
    `SELECT id, guild_id, event_type, discord_user_id, username, invite_code, inviter_id, inviter_tag, created_at
       FROM member_events ${where} ORDER BY id DESC LIMIT ? OFFSET ?`,
    params,
  )
}

async function recentFilterHits({ limit = 50, offset = 0 } = {}) {
  return query(
    `SELECT id, guild_id, hit_type, discord_user_id, username, channel_id, matched, action_taken, created_at
       FROM filter_hits ORDER BY id DESC LIMIT ? OFFSET ?`,
    [limit, offset],
  )
}

async function recentSpamHits({ limit = 50, offset = 0 } = {}) {
  return query(
    `SELECT id, guild_id, spam_type, discord_user_id, username, channel_id, created_at
       FROM spam_hits ORDER BY id DESC LIMIT ? OFFSET ?`,
    [limit, offset],
  )
}

// User-lookup: match a Discord id exactly, or a username snapshot (target_tag)
// by prefix, returning the most recently seen distinct targets. Powers the
// dashboard search box (usernames drift, so we search historical snapshots too).
async function searchTargets(term, { limit = 20 } = {}) {
  return query(
    `SELECT ma.target_user_id, MAX(ma.target_tag) AS target_tag,
            COUNT(*) AS action_count, MAX(ma.created_at) AS last_seen
       FROM mod_actions ma
      WHERE ma.target_user_id = ? OR ma.target_tag LIKE ?
      GROUP BY ma.target_user_id
      ORDER BY last_seen DESC
      LIMIT ?`,
    [term, `${term}%`, limit],
  )
}

module.exports = {
  TYPES,
  countsByWindow,
  recentActions,
  userActions,
  userCounts,
  latestTag,
  linkedAccount,
  searchTargets,
  // Phase 6b
  memberCountsByWindow,
  inviteJoinCountsByWindow,
  tableCountsByWindow,
  recentMemberEvents,
  recentFilterHits,
  recentSpamHits,
}
