/**
 * Smoke: AUTH_REQUIRED gate via Fastify inject.
 * Run: AUTH_REQUIRED=true AUTH_JWT_SECRET=test-secret-at-least-8 tsx src/plugins/auth.smoke.test.ts
 */
import assert from "node:assert/strict"
import { SignJWT } from "jose"

process.env.AUTH_REQUIRED = "true"
process.env.AUTH_JWT_SECRET = "test-secret-at-least-8"
process.env.AUTH_ISSUER = "https://auth.test.local"
process.env.AUTH_PORTAL_URL = "http://localhost:5175"
process.env.CORS_ORIGIN = "http://localhost:3000"
process.env.DATABASE_PATH = ":memory:"
process.env.NODE_ENV = "test"

// Dynamic import after env is set
const { buildApp } = await import("../index.js")

const secret = new TextEncoder().encode("test-secret-at-least-8")

async function mint(payload: Record<string, unknown>): Promise<string> {
  return new SignJWT(payload)
    .setProtectedHeader({ alg: "HS256" })
    .setIssuer("https://auth.test.local")
    .setExpirationTime("1h")
    .sign(secret)
}

const app = await buildApp({ logger: false, startScheduler: false })

const health = await app.inject({ method: "GET", url: "/health" })
assert.equal(health.statusCode, 200)

const cfg = await app.inject({ method: "GET", url: "/api/auth/config" })
assert.equal(cfg.statusCode, 200)
assert.equal(cfg.json().required, true)

const noToken = await app.inject({ method: "GET", url: "/api/sidebar-counts" })
assert.equal(noToken.statusCode, 401)

const badApp = await mint({
  sub: "u1",
  email: "a@b.c",
  name: "A",
  apps: ["cdn"],
  permissions: ["cdn:dashboard:read"],
})
const forbiddenApp = await app.inject({
  method: "GET",
  url: "/api/sidebar-counts",
  headers: { authorization: `Bearer ${badApp}` },
})
assert.equal(forbiddenApp.statusCode, 403)

const okToken = await mint({
  sub: "u1",
  email: "a@b.c",
  name: "A",
  apps: ["mm"],
  permissions: ["mm:dashboard:read"],
})
const ok = await app.inject({
  method: "GET",
  url: "/api/sidebar-counts",
  headers: { authorization: `Bearer ${okToken}` },
})
// May be 200 or 500 if DB missing — must not be 401/403
assert.notEqual(ok.statusCode, 401)
assert.notEqual(ok.statusCode, 403)

await app.close()
console.log("auth.smoke.test.ts: ok")
