import { createOauthPendingState } from "../../../../db/mail";
import {
  MS_AUTH_BASE,
  MS_REDIRECT_URI,
  MS_OAUTH_SCOPES,
  generateCodeVerifier,
  computeCodeChallenge,
  generateStateId,
} from "../../../../utils/ms-oauth";

/**
 * POST /api/mail/oauth/microsoft/init
 *
 * Step 1 of the Microsoft OAuth PKCE flow.
 * Generates a PKCE code_verifier + code_challenge, persists the state in
 * oauth_pending_states (TTL 10 min), and returns the authorization URL.
 *
 * The native app opens this URL via expo-web-browser (WebBrowser.openAuthSessionAsync).
 * After login + consent, Microsoft redirects to rebreak://auth/mail-oauth-callback?code=…&state=…
 * The app deep-link handler calls POST /api/mail/oauth/microsoft/callback with { code, state }.
 *
 * Body (optional):
 *   email?: string   — pre-fills login_hint + prompt logic
 *
 * Response:
 *   200: { authorizationUrl: string }
 *   401: not authenticated
 */
export default defineEventHandler(async (event) => {
  const user = await requireUser(event);
  const config = useRuntimeConfig(event);
  const clientId = config.msOauthClientId as string;

  if (!clientId) {
    throw createError({
      statusCode: 500,
      data: { error: "MS_OAUTH_CLIENT_ID not configured" },
    });
  }

  const body = await readBody(event).catch(() => ({})) as { email?: string };
  const hintEmail = body?.email?.trim() || null;

  // ── PKCE ─────────────────────────────────────────────────────────────────
  const codeVerifier = generateCodeVerifier();
  const codeChallenge = computeCodeChallenge(codeVerifier);
  const stateId = generateStateId();

  // ── Persist state (TTL enforced at read time in callback) ─────────────────
  // Clean up stale entries for this user (older than 10 min) before inserting.
  await createOauthPendingState({
    stateId,
    userId: user.id,
    codeVerifier,
    email: hintEmail,
  });

  // ── Build authorization URL ───────────────────────────────────────────────
  const params = new URLSearchParams({
    client_id: clientId,
    response_type: "code",
    redirect_uri: MS_REDIRECT_URI,
    response_mode: "query",
    scope: MS_OAUTH_SCOPES,
    state: stateId,
    code_challenge: codeChallenge,
    code_challenge_method: "S256",
    // prompt=consent: always show consent screen so user sees what scopes are requested.
    // Alternative: 'select_account' for re-connect flows (less friction but skips
    // scope confirmation). Using 'consent' is the safer DSGVO-aligned default.
    prompt: "consent",
  });

  if (hintEmail) {
    params.set("login_hint", hintEmail);
  }

  const authorizationUrl = `${MS_AUTH_BASE}?${params.toString()}`;

  return { authorizationUrl };
});
