/**
 * Admin-plane RBAC routes — admin-dashboard.
 * GET    /api/admin/roles        → list admin roles
 * POST   /api/admin/roles        → create custom admin role
 * PUT    /api/admin/roles/:id    → update permissions
 * DELETE /api/admin/roles/:id    → delete custom role
 */
import { Hono } from 'hono'
import { z } from 'zod'
import { createDb } from '@zync/db/queries'
import {
  listAdminRoles,
  createAdminRole,
  updateAdminRole,
  deleteAdminRole,
  AdminRoleSystemError,
  AdminRoleNotFoundError,
} from '@zync/db/queries'
import { ADMIN_PERMISSIONS } from '@zync/types'
import type { AppEnv } from '../../types'
import { adminAuthMiddleware } from '../../middleware/admin-auth'
import { requireAdminSession } from '../../middleware/guards'
import { requireAdminPermission } from '@zync/auth'

const adminRolesRoutes = new Hono<AppEnv>()

adminRolesRoutes.use('*', adminAuthMiddleware)
adminRolesRoutes.use('*', requireAdminSession())
adminRolesRoutes.use('*', requireAdminPermission('admin.roles:manage'))

const CreateAdminRoleSchema = z.object({
  name: z.string().min(1).max(64),
  permissions: z.array(z.enum(ADMIN_PERMISSIONS)).default([]),
})

const UpdateAdminRoleSchema = z.object({
  permissions: z.array(z.enum(ADMIN_PERMISSIONS)),
})

// ── List ──────────────────────────────────────────────────────────────────────

adminRolesRoutes.get('/', async (c) => {
  const db = createDb(c.env)
  const roles = await listAdminRoles(db)
  return c.json(roles)
})

// ── Create ────────────────────────────────────────────────────────────────────

adminRolesRoutes.post('/', async (c) => {
  const parsed = CreateAdminRoleSchema.safeParse(await c.req.json())
  if (!parsed.success) {
    return c.json({ error: 'Invalid request', details: parsed.error.flatten() }, 400)
  }

  const db = createDb(c.env)
  const result = await createAdminRole(db, {
    name: parsed.data.name,
    permissions: [...parsed.data.permissions],
  })

  return c.json(result, 201)
})

// ── Update ────────────────────────────────────────────────────────────────────

adminRolesRoutes.put('/:id', async (c) => {
  const id = c.req.param('id')
  const parsed = UpdateAdminRoleSchema.safeParse(await c.req.json())
  if (!parsed.success) {
    return c.json({ error: 'Invalid request', details: parsed.error.flatten() }, 400)
  }

  try {
    const db = createDb(c.env)
    await updateAdminRole(db, id, { permissions: [...parsed.data.permissions] })
    return c.json({ success: true })
  } catch (err) {
    if (err instanceof AdminRoleNotFoundError) return c.json({ error: err.message }, 404)
    if (err instanceof AdminRoleSystemError) return c.json({ error: err.message }, 403)
    throw err
  }
})

// ── Delete ────────────────────────────────────────────────────────────────────

adminRolesRoutes.delete('/:id', async (c) => {
  try {
    const db = createDb(c.env)
    await deleteAdminRole(db, c.req.param('id'))
    return c.body(null, 204)
  } catch (err) {
    if (err instanceof AdminRoleNotFoundError) return c.json({ error: err.message }, 404)
    if (err instanceof AdminRoleSystemError) return c.json({ error: err.message }, 403)
    throw err
  }
})

export { adminRolesRoutes }
