import { createOauthPendingState } from "../../../../db/mail";
import {
  GOOGLE_AUTH_BASE,
  GOOGLE_REDIRECT_URI,
  GOOGLE_OAUTH_SCOPES,
  generateCodeVerifier,
  computeCodeChallenge,
  generateStateId,
} from "../../../../utils/google-oauth";

/**
 * POST /api/mail/oauth/google/init
 *
 * Step 1 des Google OAuth PKCE-Flows.
 * Generiert PKCE code_verifier + code_challenge, persistiert State in
 * oauth_pending_states (TTL 10 min), gibt Authorization-URL zurück.
 *
 * Die native App öffnet die URL via expo-web-browser (WebBrowser.openAuthSessionAsync).
 * Nach Login + Consent leitet Google weiter auf rebreak://auth/mail-oauth-callback?code=…&state=…
 * Der Deep-Link-Handler der App ruft POST /api/mail/oauth/google/callback mit { code, state }.
 *
 * Google-Spezifik:
 *   prompt=consent   — PFLICHT damit Google refresh_token zurückgibt. Ohne das:
 *                      kein refresh_token beim Exchange → Connection lebt nur 1h.
 *   access_type=offline — PFLICHT für refresh_token (Google-spezifisch, MS braucht das nicht).
 *
 * Body (optional):
 *   email?: string   — pre-fills login_hint
 *
 * Response:
 *   200: { authorizationUrl: string }
 *   401: not authenticated
 *   500: GOOGLE_OAUTH_CLIENT_ID not configured
 */
export default defineEventHandler(async (event) => {
  const user = await requireUser(event);
  const config = useRuntimeConfig(event);
  const clientId = config.googleOauthClientId as string;

  if (!clientId) {
    throw createError({
      statusCode: 500,
      data: { error: "GOOGLE_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) ──────────────────
  await createOauthPendingState({
    stateId,
    userId: user.id,
    codeVerifier,
    email: hintEmail,
  });

  // ── Build authorization URL ─────────────────────────────────────────────────
  const params = new URLSearchParams({
    client_id: clientId,
    response_type: "code",
    redirect_uri: GOOGLE_REDIRECT_URI,
    scope: GOOGLE_OAUTH_SCOPES,
    state: stateId,
    code_challenge: codeChallenge,
    code_challenge_method: "S256",
    // access_type=offline: PFLICHT damit Google ein refresh_token ausstellt.
    // Bei access_type=online (default) gibt es keinen refresh_token.
    access_type: "offline",
    // prompt=consent: PFLICHT damit Google den refresh_token zurückgibt
    // (auch wenn der User die App schon einmal autorisiert hat).
    // Ohne das: bei bestehender Berechtigung kommt kein refresh_token.
    prompt: "consent",
  });

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

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

  return { authorizationUrl };
});
