/**
 * API key usage & quota routes — api-usage-quota-ui (wave-12).
 * Mounted at /api-keys in routes/index.ts.
 *
 * GET  /api-keys/:id/usage  — usage summary for a key (OWNER|ADMIN, settings:read, Business+)
 * PATCH /api-keys/:id/quota — update monthly_quota (OWNER only, settings:write, Business+)
 *
 * Business+ tier is enforced by requireTier('business') guard.
 * OWNER check is inline (mirrors the server-side gate for the frontend).
 */
import { Hono } from 'hono'
import { z } from 'zod'
import type { AppEnv } from '../types'
import { authMiddleware } from '../middleware/auth'
import { requirePermission, requireTier } from '../middleware/guards'
import {
  createDb,
  getApiKeyForTenant,
  updateApiKeyMonthlyQuota,
} from '@zync/db/queries'
import type {
  ApiKeyUsageResponse,
  ApiKeyQuotaResponse,
} from '@zync/types'
import { TenantTier } from '@zync/types'
import {
  getDailyUsage,
  getTopEndpoints,
  getMonthlyUsage,
} from '@zync/api-usage'

// ── Zod schemas ───────────────────────────────────────────────────────────────

const usageQuerySchema = z.object({
  month: z
    .string()
    .regex(/^\d{4}-\d{2}$/, 'month must be YYYY-MM')
    .optional(),
})

const quotaBodySchema = z.object({
  monthly_quota: z.number().int().min(0).nullable().optional(),
})

// ── Router ────────────────────────────────────────────────────────────────────

export const apiKeysUsageRoutes = new Hono<AppEnv>()

apiKeysUsageRoutes.use('*', authMiddleware)

// ── GET /api-keys/:id/usage ───────────────────────────────────────────────────
apiKeysUsageRoutes.get(
  '/:id/usage',
  requireTier(TenantTier.BUSINESS),
  requirePermission('settings:read'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    // OWNER or ADMIN only
    const role = (session as { role?: string }).role ?? ''
    if (role !== 'owner' && role !== 'OWNER' && role !== 'admin' && role !== 'ADMIN') {
      return c.json({ error: 'Owner or Admin role required' }, 403)
    }

    const { id } = c.req.param()
    const rawQuery = c.req.query()
    const parsed = usageQuerySchema.safeParse(rawQuery)
    if (!parsed.success) {
      return c.json({ error: 'Validation failed', issues: parsed.error.issues }, 400)
    }

    const db = createDb(c.env)
    const key = await getApiKeyForTenant(db, session.tid, id)
    if (!key) return c.json({ error: 'Not found' }, 404)

    const month = parsed.data.month

    const [used, daily, topEndpoints] = await Promise.all([
      getMonthlyUsage(c.env, session.tid, id, month),
      getDailyUsage(c.env, session.tid, id, month),
      getTopEndpoints(c.env, session.tid, id, month),
    ])

    const quota = key.monthlyQuota ?? null
    const remaining = quota !== null ? Math.max(0, quota - used) : null

    const response: ApiKeyUsageResponse = {
      used,
      quota,
      remaining,
      daily,
      topEndpoints,
    }
    return c.json(response, 200)
  },
)

// ── PATCH /api-keys/:id/quota ─────────────────────────────────────────────────
apiKeysUsageRoutes.patch(
  '/:id/quota',
  requireTier(TenantTier.BUSINESS),
  requirePermission('settings:write'),
  async (c) => {
    const session = c.get('session')
    if (!session || session.type !== 'user' || !session.tid) {
      return c.json({ error: 'Unauthorized' }, 401)
    }

    // OWNER only
    const role = (session as { role?: string }).role ?? ''
    if (role !== 'owner' && role !== 'OWNER') {
      return c.json({ error: 'Owner role required to update quota' }, 403)
    }

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

    const monthlyQuota = parsed.data.monthly_quota ?? null

    const db = createDb(c.env)
    const updated = await updateApiKeyMonthlyQuota(
      db,
      session.tid,
      id,
      monthlyQuota,
      session.sub,
    )
    if (!updated) return c.json({ error: 'Not found' }, 404)

    const response: ApiKeyQuotaResponse = {
      id: updated.id,
      monthly_quota: updated.monthly_quota,
    }
    return c.json(response, 200)
  },
)
