import type { APIRoute } from 'astro';
import { env, getBaseUrlFromRequest } from '../../../lib/env';
import { STATE_COOKIE, parseCookies, clearCookie, setSessionCookie, CSRF_COOKIE } from '../../../lib/session';
import { createCsrfToken } from '../../../lib/csrf';

export const GET: APIRoute = async ({ request }) => {
  const url = new URL(request.url);
  const code = url.searchParams.get('code');
  const state = url.searchParams.get('state');
  const cookies = parseCookies(request.headers.get('cookie'));

  if (!code || !state || cookies[STATE_COOKIE] !== state) {
    return new Response('Invalid OAuth state', { status: 400 });
  }

  if (!env.OAUTH_CLIENT_ID || !env.OAUTH_CLIENT_SECRET || !env.OAUTH_TOKEN_URL || !env.OAUTH_USERINFO_URL) {
    return new Response('OAuth not fully configured', { status: 500 });
  }

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

  // Exchange code for token
  let token: string;
  try {
    const res = await fetch(env.OAUTH_TOKEN_URL!, {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        client_id: env.OAUTH_CLIENT_ID!,
        client_secret: env.OAUTH_CLIENT_SECRET!,
        code,
        grant_type: 'authorization_code',
        redirect_uri: redirectUri,
      }),
    });
    if (!res.ok) {
      const txt = await res.text();
      return new Response(`Token exchange failed: ${res.status} ${txt}`, { status: 500 });
    }
    const data = await res.json().catch(async () => {
      // Some providers may return querystring
      const text = await res.text();
      const params = new URLSearchParams(text);
      return { access_token: params.get('access_token') };
    });
    token = data.access_token;
    if (!token) throw new Error('No access_token');
  } catch (e: any) {
    return new Response(`Token error: ${e?.message || e}`, { status: 500 });
  }

  // Fetch user info
  const userRes = await fetch(env.OAUTH_USERINFO_URL!, {
    headers: { Authorization: `token ${token}` },
  });
  if (!userRes.ok) {
    const txt = await userRes.text();
    return new Response(`Userinfo error: ${userRes.status} ${txt}`, { status: 500 });
  }
  const user = await userRes.json();

  // Optional allow list
  if (env.OAUTH_ALLOWED_USERS) {
    const allowed = env.OAUTH_ALLOWED_USERS.split(',').map((s) => s.trim()).filter(Boolean);
    if (!allowed.includes(user?.login || user?.username)) {
      return new Response('forbidden', { status: 403 });
    }
  }

  // Create session and CSRF
  const sessionHeader = setSessionCookie({ user: { id: user.id, username: user.login || user.username, email: user.email, displayName: user.full_name || user.name } });
  const csrf = createCsrfToken();
  // CSRF cookie should NOT be HttpOnly so frontend can read it and send in header
  const csrfHeader = `${CSRF_COOKIE}=${csrf}; Path=/; SameSite=Lax${process.env.NODE_ENV === 'production' ? '; Secure' : ''}`;

  const headers = new Headers({ Location: '/admin' });
  headers.append('Set-Cookie', clearCookie(STATE_COOKIE));
  headers.append('Set-Cookie', sessionHeader);
  headers.append('Set-Cookie', csrfHeader);
  headers.append('Cache-Control', 'no-store');

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