/**
 * POST /oauth/revoke — token revocation (wave-12).
 *
 * RFC 7009 compliant. Accepts access_token or refresh_token.
 * Returns 200 regardless of whether the token exists (idempotent).
 */
import { Hono } from 'hono'
import { z } from 'zod'
import { hashToken } from '@zync/auth'
import {
  createDb,
  revokeAccessTokenByHash,
  revokeRefreshTokenByHash,
  revokeAccessTokensByFamily,
} from '@zync/db/queries'
import type { AppEnv } from '../../types'

const revokeBodySchema = z.record(z.string(), z.string())

const revokeRoute = new Hono<AppEnv>()

revokeRoute.post('/revoke', async (c) => {
  let body: Record<string, string>
  const ct = c.req.header('content-type') ?? ''
  if (ct.includes('application/x-www-form-urlencoded')) {
    const form = await c.req.formData()
    body = Object.fromEntries(form.entries()) as Record<string, string>
  } else {
    try {
      const jsonResult = revokeBodySchema.safeParse(await c.req.json())
      if (!jsonResult.success) return c.json({ error: 'invalid_request' }, 400)
      body = jsonResult.data
    } catch {
      return c.json({ error: 'invalid_request' }, 400)
    }
  }

  const { token, token_type_hint: typeHint } = body
  if (!token) return c.json({ error: 'invalid_request', error_description: 'token is required' }, 400)

  const db = createDb(c.env)
  const hash = await hashToken(token)

  if (typeHint !== 'refresh_token') {
    // Try access token
    const revoked = await revokeAccessTokenByHash(db, hash)
    if (revoked) {
      // Evict KV cache entry if present
      await c.env.RATELIMIT_KV.delete(`oauth_at:${hash}`)
      return c.json({ revoked: true })
    }
  }

  // Try refresh token
  const familyId = await revokeRefreshTokenByHash(db, hash)
  if (familyId) {
    await revokeAccessTokensByFamily(db, familyId)
    // Evict KV cache for all access tokens in family (best-effort)
    return c.json({ revoked: true })
  }

  // Not found — RFC 7009 says return 200 anyway
  return c.json({ revoked: false })
})

export { revokeRoute }
