/**
 * Admin session management routes — session-security (wave-13).
 * Mounted at /api/admin/sessions.
 * Requires Business+ tier and settings:security:read/write (tenant OWNER/ADMIN).
 *
 * GET  /                     → list all active sessions for the tenant (grouped by user)
 * DELETE /user/:userId        → revoke all sessions for a specific user
 * DELETE /                   → revoke all sessions for the entire team
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../types'
import { authMiddleware } from '../middleware/auth'
import { requirePermission, requireTier } from '../middleware/guards'
import {
  listTenantUserSessionSummaries,
  revokeAllSessionsForUser,
  revokeAllTenantSessions,
} from '@zync/db/queries'
import { blocklistRevokedTokens } from '@zync/auth'
import { logAuditEvent } from '@zync/db/queries'
import { TenantTier } from '@zync/types'

export const adminSessionsRoute = new Hono<AppEnv>()

adminSessionsRoute.use('*', authMiddleware)
adminSessionsRoute.use('*', requireTier(TenantTier.BUSINESS))

// ── GET /api/admin/sessions ───────────────────────────────────────────────────

adminSessionsRoute.get('/', requirePermission('settings:security:read'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const db = c.get('db')
  const tenantId = session.tid
  const summaries = await listTenantUserSessionSummaries(db, tenantId)

  return c.json({ sessions: summaries }, 200)
})

// ── DELETE /api/admin/sessions/user/:userId ───────────────────────────────────

const userIdSchema = z.object({ userId: z.string().uuid() })

adminSessionsRoute.delete('/user/:userId', requirePermission('settings:security:write'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const parsed = userIdSchema.safeParse({ userId: c.req.param('userId') })
  if (!parsed.success) return c.json({ error: 'Invalid user id' }, 400)

  const db = c.get('db')
  const tenantId = session.tid
  const { tokens } = await revokeAllSessionsForUser(db, parsed.data.userId, tenantId, 'admin')

  if (tokens.length > 0) {
    await blocklistRevokedTokens(c.env.RATELIMIT_KV, tokens)
  }

  void logAuditEvent({ env: c.env }, {
    tenantId,
    userId: session.sub,
    eventType: 'auth.sessions_revoked',
    metadata: { targetUserId: parsed.data.userId, count: tokens.length, scope: 'user' },
  })

  return c.json({ ok: true, revoked: tokens.length }, 200)
})

// ── DELETE /api/admin/sessions ────────────────────────────────────────────────

const bulkRevokeBodySchema = z.object({ confirm: z.literal('revoke all') })

adminSessionsRoute.delete('/', requirePermission('settings:security:write'), async (c) => {
  const session = c.get('session')
  if (!session || session.type !== 'user' || !session.tid) {
    return c.json({ error: 'Unauthorized' }, 401)
  }

  const body = await c.req.json().catch(() => null)
  const parsed = bulkRevokeBodySchema.safeParse(body)
  if (!parsed.success) {
    return c.json({ error: 'Confirmation required: send { "confirm": "revoke all" }' }, 400)
  }

  const db = c.get('db')
  const tenantId = session.tid
  const { tokens } = await revokeAllTenantSessions(db, tenantId, 'admin')

  if (tokens.length > 0) {
    await blocklistRevokedTokens(c.env.RATELIMIT_KV, tokens)
  }

  void logAuditEvent({ env: c.env }, {
    tenantId,
    userId: session.sub,
    eventType: 'auth.sessions_revoked',
    metadata: { scope: 'entire_tenant', count: tokens.length },
  })

  return c.json({ ok: true, revoked: tokens.length }, 200)
})
