import { db } from '@/lib/db';
import { getSession } from '@/src/lib/auth';
import { createRedirectResponse } from '@/src/lib/api';
import qs from 'qs';
import { NextRequest } from 'next/server';
import { cookies } from 'next/headers';

export async function GET(req: NextRequest) {
  try {
    const session = await getSession();
    const { searchParams } = new URL(req.url);
    const code = searchParams.get('code');
    const state = searchParams.get('state');
    const cookieStore = await cookies();
    const csrf = cookieStore.get('csrf')?.value;

    if (!code || !state || !csrf || state !== csrf) {
      return createRedirectResponse('/dashboard', { error: 'invalid_request' });
    }

    const accessToken = await exchangeOAuthToken(code);
    if (!accessToken) {
      return createRedirectResponse('/dashboard', {
        error: 'oauth_failed',
      });
    }

    if (!session?.user?.email) {
      return createRedirectResponse('/dashboard', { error: 'invalid_request' });
    }

    const result = await db.user.update({
      where: {
        email: session?.user?.email,
      },
      data: {
        vercelAccessToken: accessToken,
      },
    });

    if (!result) {
      return createRedirectResponse('/projects', {
        error: 'token_update_failed',
      });
    }

    return createRedirectResponse('/dashboard', { oauth: 'success' });
  } catch {
    return createRedirectResponse('/dashboard', { error: 'oauth_failed' });
  }
}

async function exchangeOAuthToken(code: string): Promise<string | null> {
  try {
    const params = qs.stringify({
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
      code,
      redirect_uri: process.env.REDIRECT_URI,
    });

    const response = await fetch('https://api.vercel.com/v2/oauth/access_token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: params,
    });

    if (!response.ok) {
      throw new Error('Failed to exchange OAuth token');
    }

    const data = await response.json();
    return data.access_token;
  } catch {
    return null;
  }
}
