// Shared formatting for shard events — used by the public Shard page, the
// Activity feed, and the admin live feed. One place decides how each kind reads
// and which category/badge it belongs to.

function nameOf(who) {
  if (!who) return 'Someone'
  if (typeof who === 'string') return who
  return who.name || who.acct || 'Someone'
}

const n = (v) => Number(v || 0).toLocaleString()

// A one-line human description of an event. Accepts either a stored event
// (with .payload) or a raw live frame (fields at top level).
export function describe(ev) {
  const p = ev.payload || ev
  switch (ev.kind) {
    case 'vendor.sale':
      return `${p.itemType || 'An item'}${p.amount > 1 ? ` ×${p.amount}` : ''} sold for ${n(p.price)}gp`
    case 'player.death':
      return `${nameOf(p.who)} was slain${p.killer ? ` by ${nameOf(p.killer)}` : ''}`
    case 'player.murdered':
      return `${nameOf(p.victim)} was murdered${p.murderer ? ` by ${nameOf(p.murderer)}` : ''}`
    case 'mob.killed':
      return `${nameOf(p.killer)} killed ${nameOf(p.killed)}`
    case 'skill.gain':
      return `${nameOf(p.who)} gained ${p.skill}${p.base != null ? ` (${p.base})` : ''}`
    case 'fame.change':
      return `${nameOf(p.who)}’s fame changed to ${n(p.new)}`
    case 'karma.change':
      return `${nameOf(p.who)}’s karma changed to ${n(p.new)}`
    case 'quest.complete':
      return `${nameOf(p.who)} completed “${p.quest}”`
    case 'house.decay':
      return `${p.name || 'A house'} is now ${p.to || p.stage}${p.region ? ` — ${p.region}` : ''}`
    case 'mob.login':
      return `${nameOf(p.who)} entered the world`
    case 'mob.logout':
      return `${nameOf(p.who)} left the world`
    case 'economy.supply':
      return `Gold supply: ${n(p.gold)} across ${n(p.accounts)} accounts`
    case 'server.hello':
      return `Shard online — ${n(p.accounts)} accounts, ${n(p.mobiles)} mobiles`
    case 'server.shutdown':
      return 'Shard shut down'
    case 'server.crashed':
      return `Shard crashed${p.error ? `: ${p.error}` : ''}`
    case 'champ.update': {
      const where = p.name || p.type || 'A champion spawn'
      if (p.status === 'active' && p.bossUp) return `${where}: boss is up${p.boss ? ` (${p.boss})` : ''}`
      if (p.status === 'active') return `${where} is active${p.level != null ? ` — level ${p.level}` : ''}`
      if (p.status === 'cooldown') return `${where} is on cooldown`
      return `${where} is ${p.status || 'idle'}`
    }
    case 'champ.remove':
      return `A champion spawn ended`
    // Support (help-page) queue + in-game moderation (admin channel only)
    case 'page.new':
      return `New ${p.type || 'help'} page from ${nameOf(p.sender)}`
    case 'page.updated':
      return `Help page from ${nameOf(p.sender)} updated${p.handled ? ' (claimed)' : ''}`
    case 'page.closed':
      return `Help page ${p.pageId || ''} closed`
    case 'admin.audit':
      return `${p.actor || 'Staff'} ${p.action || 'acted'}${p.target ? ` on ${p.target}` : ''}${p.origin ? ` [${p.origin}]` : ''}`
    // Staff / sensitive (admin channel only)
    case 'audit.set':
      return `${nameOf(p.staff) || 'Staff'} set ${p.prop} on ${p.target || p.targetSerial} (${p.old} → ${p.new})`
    case 'audit.command':
      return `${nameOf(p.staff) || 'Staff'} ran ${p.command}${p.args ? ` ${p.args}` : ''}`
    case 'cheat.fastwalk':
      return `Fast-walk flagged: ${nameOf(p.who)}${p.ip ? ` (${p.ip})` : ''}`
    case 'account.login.attempt':
      return `Login attempt: ${p.acct}${p.ip ? ` from ${p.ip}` : ''}`
    case 'gold.change':
      return `${p.acct}: gold ${p.delta >= 0 ? '+' : ''}${n(p.delta)} → ${n(p.new)}`
    default:
      return ev.kind
  }
}

// Category grouping for the filter tabs.
// Vendor sales are intentionally NOT a public category — they are owner-private
// (a linked player sees their own under the portal). The admin live feed still
// describes vendor.sale via describe() below.
export const CATEGORIES = [
  { id: 'all', label: 'All', kinds: null },
  { id: 'pvp', label: 'Deaths & PvP', kinds: ['player.death', 'player.murdered', 'mob.killed'] },
  { id: 'progress', label: 'Progression', kinds: ['skill.gain', 'fame.change', 'karma.change', 'quest.complete'] },
  { id: 'world', label: 'World', kinds: ['house.decay', 'mob.login', 'mob.logout', 'server.hello', 'server.shutdown', 'server.crashed', 'economy.supply'] },
]

const CATEGORY_OF = (() => {
  const m = {}
  for (const c of CATEGORIES) if (c.kinds) for (const k of c.kinds) m[k] = c.id
  return m
})()

export function categoryOf(kind) {
  return CATEGORY_OF[kind] || 'other'
}

// Short badge label for a kind (the part after the dot, title-cased-ish).
export function kindLabel(kind) {
  return String(kind || '').replace(/[._]/g, ' ')
}
