import type { APIRoute } from 'astro';
import { env, getBaseUrlFromRequest } from '../../../lib/env';
import { STATE_COOKIE, setTempCookie, cookieAttrs } from '../../../lib/session';

export const GET: APIRoute = async ({ request }) => {
  if (!env.OAUTH_CLIENT_ID || !env.OAUTH_AUTHORIZE_URL) {
    return new Response('OAuth not configured. Set OAUTH_CLIENT_ID and OAUTH_AUTHORIZE_URL.', { status: 500 });
  }

  const state = cryptoRandomString();
  const base = getBaseUrlFromRequest(request);
  const redirectUri = `${base}/api/auth/callback`;

  let authUrl: URL;
  try {
    authUrl = new URL(env.OAUTH_AUTHORIZE_URL!);
  } catch {
    return new Response('Invalid OAUTH_AUTHORIZE_URL', { status: 500 });
  }

  authUrl.searchParams.set('client_id', env.OAUTH_CLIENT_ID!);
  authUrl.searchParams.set('redirect_uri', redirectUri);
  authUrl.searchParams.set('response_type', 'code');
  authUrl.searchParams.set('state', state);

  const headers = new Headers({ Location: authUrl.toString() });
  headers.append('Set-Cookie', setTempCookie(STATE_COOKIE, state, 600));
  // also ensure any previous session cookies aren't cached
  headers.append('Cache-Control', 'no-store');

  return new Response(null, { status: 302, headers });
};

function cryptoRandomString(len = 24) {
  const bytes = crypto.getRandomValues(new Uint8Array(len));
  return Buffer.from(bytes).toString('base64url');
}

// ensure Web Crypto for Node
import crypto from 'node:crypto';
if (!(globalThis as any).crypto?.getRandomValues) {
  (globalThis as any).crypto = {
    getRandomValues: (arr: Uint8Array) => (crypto.webcrypto.getRandomValues(arr))
  } as any;
}
