/**
 * Admin tenant roles API routes — admin-dashboard.
 * GET  /api/admin/tenants/:slug/roles          → list tenant roles with permissions
 * POST /api/admin/tenants/:slug/roles          → create custom role
 * PUT  /api/admin/tenants/:slug/roles/:roleId  → update custom role permissions
 * DELETE /api/admin/tenants/:slug/roles/:roleId → delete custom role
 */
import { Hono } from 'hono'
import { z } from 'zod'
import { createDb } from '@zync/db/queries'
import {
  getTenantDetailAdmin,
  listTenantRolesAdmin,
  createTenantRole,
  updateTenantRolePermissions,
  deleteTenantRole,
} from '@zync/db/queries'
import type { AppEnv } from '../../types'
import { adminAuthMiddleware } from '../../middleware/admin-auth'
import { requireAdminSession } from '../../middleware/guards'
import { requireAdminPermission } from '@zync/auth'

const adminTenantRolesRoutes = new Hono<AppEnv>()

adminTenantRolesRoutes.use('*', adminAuthMiddleware)
adminTenantRolesRoutes.use('*', requireAdminSession())

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

const UpdateRoleSchema = z.object({
  permissions: z.array(z.string()),
})

// ── List roles ────────────────────────────────────────────────────────────────

adminTenantRolesRoutes.get(
  '/:slug/roles',
  requireAdminPermission('admin.tenants:read'),
  async (c) => {
    const slug = c.req.param('slug')
    const db = createDb(c.env)
    const tenant = await getTenantDetailAdmin(db, slug)
    if (!tenant) return c.json({ error: 'Tenant not found' }, 404)

    const roles = await listTenantRolesAdmin(db, tenant.id)
    return c.json(roles)
  },
)

// ── Create role ───────────────────────────────────────────────────────────────

adminTenantRolesRoutes.post(
  '/:slug/roles',
  requireAdminPermission('admin.tenants:write'),
  async (c) => {
    const slug = c.req.param('slug')
    const parsed = CreateRoleSchema.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 tenant = await getTenantDetailAdmin(db, slug)
    if (!tenant) return c.json({ error: 'Tenant not found' }, 404)

    const result = await createTenantRole(
      db,
      tenant.id,
      parsed.data.name,
      parsed.data.permissions,
    )

    return c.json(result, 201)
  },
)

// ── Update role permissions ───────────────────────────────────────────────────

adminTenantRolesRoutes.put(
  '/:slug/roles/:roleId',
  requireAdminPermission('admin.tenants:write'),
  async (c) => {
    const slug = c.req.param('slug')
    const roleId = c.req.param('roleId')
    const parsed = UpdateRoleSchema.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 tenant = await getTenantDetailAdmin(db, slug)
    if (!tenant) return c.json({ error: 'Tenant not found' }, 404)

    const result = await updateTenantRolePermissions(
      db,
      tenant.id,
      roleId,
      parsed.data.permissions,
    )

    if (!result.success) {
      const status = result.error === 'Role not found' ? 404 : 403
      return c.json({ error: result.error }, status)
    }

    return c.json({ success: true })
  },
)

// ── Delete role ───────────────────────────────────────────────────────────────

adminTenantRolesRoutes.delete(
  '/:slug/roles/:roleId',
  requireAdminPermission('admin.tenants:write'),
  async (c) => {
    const slug = c.req.param('slug')
    const roleId = c.req.param('roleId')

    const db = createDb(c.env)
    const tenant = await getTenantDetailAdmin(db, slug)
    if (!tenant) return c.json({ error: 'Tenant not found' }, 404)

    const result = await deleteTenantRole(db, tenant.id, roleId)

    if (!result.success) {
      if (result.error === 'Role not found') return c.json({ error: result.error }, 404)
      if (result.error?.includes('Cannot delete')) return c.json({ error: result.error }, 409)
      return c.json({ error: result.error }, 403)
    }

    return c.body(null, 204)
  },
)

export { adminTenantRolesRoutes }
