/**
 * POST /api/auth/logout — foundation-auth-rbac (Task 12).
 *
 * Revokes the presented refresh token, revokes the user_sessions row,
 * adds the access token to the KV blocklist (canonical session:revoked key
 * plus legacy blocklist: key), clears both cookies.
 * Idempotent: an already-revoked session still returns 204. Mounted BEHIND
 * authMiddleware (which set `session` + `accessTokenHash`).
 */
import { Hono } from 'hono'
import { getCookie } from 'hono/cookie'
import { blocklistToken, hashToken } from '@zync/auth'
import { createDb, revokeRefreshToken, revokeSessionByTokenHash } from '@zync/db/queries'
import type { AppEnv } from '../../types'
import { REFRESH_COOKIE, clearAuthCookies } from '../../lib/cookies'

export const logoutRoute = new Hono<AppEnv>()

logoutRoute.post('/logout', async (c) => {
  const db = createDb(c.env)

  // Revoke the refresh token if one was presented.
  const refresh = getCookie(c, REFRESH_COOKIE)
  if (refresh) {
    const refreshHash = await hashToken(refresh)
    await revokeRefreshToken(db, refreshHash)
  }

  const session = c.get('session')
  const accessTokenHash = c.get('accessTokenHash')
  if (accessTokenHash && session) {
    const revoked = await revokeSessionByTokenHash(db, accessTokenHash, 'user')
    const expiresAt = revoked?.expiresAt ?? new Date(session.exp * 1000)
    await blocklistToken(c.env.RATELIMIT_KV, accessTokenHash, expiresAt)

    const remaining = session.exp - Math.floor(Date.now() / 1000)
    if (remaining > 0) {
      await c.env.KV.put(`blocklist:${accessTokenHash}`, '1', { expirationTtl: remaining })
    }
  }

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