/**
 * Tenant security settings routes — session-security (wave-13).
 * Mounted at /api/settings/security.
 *
 * GET  / → getTenantSecuritySettings(tenantId)
 * PUT  / → upsertTenantSecuritySettings; advanced fields require Business+.
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../types'
import { authMiddleware } from '../middleware/auth'
import { requirePermission } from '../middleware/guards'
import { getTenantSecuritySettings, upsertTenantSecuritySettings } from '@zync/db/queries'
import { logAuditEvent } from '@zync/db/queries'
import { TenantTier } from '@zync/types'

export const securitySettingsRoute = new Hono<AppEnv>()

securitySettingsRoute.use('*', authMiddleware)

// ── GET /api/settings/security ────────────────────────────────────────────────

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

  const db = c.get('db')
  const tenantId = (session as { tid: string }).tid
  const settings = await getTenantSecuritySettings(db, tenantId)

  return c.json({
    idleTimeoutMinutes: settings.idleTimeoutMinutes,
    maxSessionsPerUser: settings.maxSessionsPerUser,
    require2faForRoles: settings.require2faForRoles,
    blockSuspiciousLogins: settings.blockSuspiciousLogins,
  }, 200)
})

// ── PUT /api/settings/security ────────────────────────────────────────────────

const securitySettingsSchema = z.object({
  idleTimeoutMinutes: z.number().int().min(5).max(10080).nullable().optional(),
  maxSessionsPerUser: z.number().int().min(1).max(100).optional(),
  require2faForRoles: z.array(z.string()).optional(),
  blockSuspiciousLogins: z.boolean().optional(),
})

// Advanced fields that require Business+ tier.
const ADVANCED_FIELDS = ['require2faForRoles', 'blockSuspiciousLogins'] as const

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

  const body = await c.req.json().catch(() => null)
  const parsed = securitySettingsSchema.safeParse(body)
  if (!parsed.success) {
    return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
  }

  const data = parsed.data
  const userSession = session as { tid: string; tier?: string }
  const tier = (userSession as { tier?: string }).tier as TenantTier | undefined

  // Block advanced fields for non-Business tenants.
  const hasAdvancedField = ADVANCED_FIELDS.some((f) => data[f] !== undefined)
  if (hasAdvancedField) {
    const isBusinessPlus = tier && [TenantTier.BUSINESS, TenantTier.ENTERPRISE, TenantTier.WHITE_LABEL].includes(tier as TenantTier)
    if (!isBusinessPlus) {
      return c.json({ error: 'Upgrade required', requiredTier: TenantTier.BUSINESS }, 402)
    }
  }

  const db = c.get('db')
  const tenantId = userSession.tid

  const updated = await upsertTenantSecuritySettings(db, tenantId, {
    idleTimeoutMinutes: data.idleTimeoutMinutes,
    maxSessionsPerUser: data.maxSessionsPerUser,
    require2faForRoles: data.require2faForRoles,
    blockSuspiciousLogins: data.blockSuspiciousLogins,
  })

  void logAuditEvent({ env: c.env }, {
    tenantId,
    userId: session.sub,
    eventType: 'settings.updated',
    metadata: { field: 'security_settings', changes: Object.keys(data) },
  })

  return c.json({
    idleTimeoutMinutes: updated.idleTimeoutMinutes,
    maxSessionsPerUser: updated.maxSessionsPerUser,
    require2faForRoles: updated.require2faForRoles,
    blockSuspiciousLogins: updated.blockSuspiciousLogins,
  }, 200)
})
