/**
 * GET /api/me — returns the authenticated user's identity and assigned color.
 *
 * Flow (normal — OIDC active):
 *   1. getAuth(c) reads iss + sub from the OIDC session JWT cookie
 *      (validated and refreshed by oidcAuthMiddleware — never reaches here unauthenticated)
 *   2. Derives displayName from OIDC claims (name → preferred_username → email → sub fallback)
 *      then calls upsertUser(iss, sub, displayName) — writes on first visit, corrects a
 *      previously blank displayName on subsequent visits (idempotent, keyed on iss+sub, D-10)
 *   3. Returns { user: { id, displayName, color } }
 *
 * Flow (dev bypass — DEV_AUTH_BYPASS=true, non-production):
 *   devAuthBypass() injects DEV_USER via c.set('user', DEV_USER). oidcAuthMiddleware
 *   is NOT mounted in index.ts when the bypass is active, so getAuth(c) is never called.
 *   This handler reads c.get('user') first and short-circuits to return the dev identity
 *   directly, skipping the DB upsert.
 *
 * The OIDC session cookie is httpOnly + Secure + SameSite (T-02-03).
 * No credential or refresh-token data is included in the response (T-02-04).
 */

import { Hono } from 'hono';
import { getAuth } from '../auth/middleware.js';
import { upsertUser, deriveDisplayName } from '../auth/user.js';
// Side-effect import: brings in the ContextVariableMap augmentation for c.get('user')
import '../auth/devBypass.js';

export const meRouter = new Hono();

meRouter.get('/', async (c) => {
  // Dev-auth bypass path: devAuthBypass() sets c.get('user') to DEV_USER when active.
  // Return the injected dev identity directly — no DB round-trip, no OIDC session needed.
  const devUser = c.get('user');
  if (devUser) {
    return c.json({
      user: {
        id: devUser.id,
        displayName: devUser.displayName,
        color: devUser.color,
      },
    });
  }

  // Normal OIDC path: getAuth returns null only if the session is invalid.
  // oidcAuthMiddleware on /api/* redirects unauthenticated requests before this handler
  // is reached, so null here indicates a genuine session error.
  const auth = await getAuth(c);
  if (!auth) {
    return c.json({ error: 'Unauthorized' }, 401);
  }

  // iss and sub are the stable identity fields — identity is always keyed on iss+sub (D-10).
  const iss = (auth.iss as string | undefined) ?? '';
  const sub = auth.sub ?? '';

  // Derive the best available display name from OIDC claims (name →
  // preferred_username → email → sub fallback). Shared helper keeps every
  // upsert call site in agreement (see deriveDisplayName).
  const displayName = deriveDisplayName(auth);

  const user = await upsertUser(iss, sub, displayName);

  if (!user) {
    return c.json({ error: 'Could not resolve user' }, 500);
  }

  return c.json({
    user: {
      id: user.id,
      displayName: user.displayName,
      color: user.color,
    },
  });
});
