/**
 * Tenant 2FA enforcement settings — auth-2fa (Task 8).
 *
 * PATCH /api/settings/security          — update enforce_2fa / disable_2fa_remember_device
 * GET   /api/settings/security/members  — count members with/without 2FA
 *
 * Requires: authMiddleware + require2FAIfEnforced + requirePermission('settings:write')
 */
import { Hono } from 'hono'
import { requirePermission } from '@zync/auth'
import {
  createDb,
  updateTenant2FASettings,
  getMember2FAStats,
  getActiveMemberIds,
  revokeAllTrustedDevicesForTenant,
} from '@zync/db/queries'
import type { TenantId, UserId } from '@zync/types'
import type { AppEnv } from '../../types'
import { securitySettingsSchema } from '../../schemas/2fa'
import { bumpUserVersion } from '../../middleware/user-version'

export const securitySettingsRoute = new Hono<AppEnv>()

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

    const parsed = securitySettingsSchema.safeParse(await c.req.json())
    if (!parsed.success) {
      return c.json({ error: 'Invalid request', details: parsed.error.issues }, 400)
    }

    const { enforce_2fa, disable_2fa_remember_device } = parsed.data
    const tenantId = session.tid as TenantId
    const actorId = session.sub as UserId
    const ip = c.req.header('CF-Connecting-IP') ?? 'unknown'

    const db = createDb(c.env)

    // Update tenant settings
    await updateTenant2FASettings(db, {
      tenantId,
      enforce2fa: enforce_2fa,
      disable2faRememberDevice: disable_2fa_remember_device,
      actorId,
      actorIp: ip,
    })

    // If enabling enforce_2fa, bump user_version for all active members
    // so their refreshed tokens carry the new flag within <=60s.
    if (enforce_2fa === true) {
      const memberIds = await getActiveMemberIds(db, tenantId)
      await Promise.all(memberIds.map((uid) => bumpUserVersion(c.env, uid)))
    }

    // If disabling remember-device, revoke all trusted devices for the tenant
    if (disable_2fa_remember_device === true) {
      await revokeAllTrustedDevicesForTenant(db, tenantId, actorId, { actorIp: ip })
    }

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

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

    const db = createDb(c.env)
    const stats = await getMember2FAStats(db, session.tid as TenantId)

    return c.json(stats, 200)
  },
)
