/**
 * Admin — Module override routes.
 *
 * PATCH /api/admin/tenants/:tenantId/modules/:moduleId
 *
 * Only accessible to verified admin sessions (type='admin', totp_verified=true).
 * Bypasses dependency checks; sets override_by_system_admin=true.
 * Action is written to the audit log in the same transaction as the state change.
 *
 * No raw Drizzle tables per `no-raw-drizzle-from-routes` ESLint rule.
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../types'
import { requireAdminSession } from '../middleware/guards'
import { adminAuthMiddleware } from '../middleware/admin-auth'
import { setModuleStateAdmin } from '@zync/db/queries'
import { MODULE_BY_ID, type ModuleId } from '@zync/modules'
import type { AdminSessionPayload } from '@zync/types'

export const adminModulesRoutes = new Hono<AppEnv>()
adminModulesRoutes.use('*', adminAuthMiddleware)

const patchBodySchema = z.object({
  enabled: z.boolean(),
  reason: z.string().min(1, 'reason is required'),
})

// ---------------------------------------------------------------------------
// PATCH /api/admin/tenants/:tenantId/modules/:moduleId
// ---------------------------------------------------------------------------
adminModulesRoutes.patch(
  '/tenants/:tenantId/modules/:moduleId',
  requireAdminSession(),
  async (c) => {
    const session = c.get('session') as AdminSessionPayload
    const { tenantId, moduleId: rawModuleId } = c.req.param()
    const moduleId = rawModuleId as ModuleId

    // Validate request body
    const body = await c.req.json().catch(() => null)
    const bodyResult = patchBodySchema.safeParse(body)
    if (!bodyResult.success) {
      return c.json({ error: 'invalid_body', issues: bodyResult.error.issues }, 400)
    }
    const { enabled, reason } = bodyResult.data

    // Validate moduleId is known
    if (!(moduleId in MODULE_BY_ID)) {
      return c.json({ error: 'not_found' }, 404)
    }

    // system module is always-on — not even admins can override
    if (moduleId === 'system') {
      return c.json({ error: 'module_always_on', module: 'system' }, 422)
    }

    const db = c.get('db')

    await setModuleStateAdmin(db, tenantId, moduleId, enabled, session.sub, reason)

    return c.json({ updated: [moduleId], overrideApplied: true })
  },
)
