import { NextRequest, NextResponse } from 'next/server';
import { getSession } from '@/lib/auth';
import { db, schema } from '@/lib/db';
import { eq, and } from 'drizzle-orm';

export async function GET(request: NextRequest) {
  const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000';
  const { searchParams } = new URL(request.url);
  const code = searchParams.get('code');
  const state = searchParams.get('state');
  const error = searchParams.get('error');

  if (error) return NextResponse.redirect(`${appUrl}/?bitbucket_error=${error}`);
  if (!code || !state) return NextResponse.redirect(`${appUrl}/?bitbucket_error=missing_params`);

  const session = await getSession(request.cookies.get('scriba.access_token')?.value);
  if (!session || session.user.id !== state) return NextResponse.redirect(`${appUrl}/?bitbucket_error=invalid_state`);

  const credentials = Buffer.from(
    `${process.env.BITBUCKET_CLIENT_ID}:${process.env.BITBUCKET_CLIENT_SECRET}`
  ).toString('base64');

  const tokenRes = await fetch('https://bitbucket.org/site/oauth2/access_token', {
    method: 'POST',
    headers: {
      Authorization: `Basic ${credentials}`,
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code,
      redirect_uri: `${appUrl}/api/auth/bitbucket/callback`,
    }),
  });

  const tokenData = await tokenRes.json();
  if (!tokenData.access_token) return NextResponse.redirect(`${appUrl}/?bitbucket_error=token_exchange_failed`);

  const userRes = await fetch('https://api.bitbucket.org/2.0/user', {
    headers: { Authorization: `Bearer ${tokenData.access_token}` },
  });
  const bbUser = await userRes.json();

  const existing = await db.query.accounts.findFirst({
    where: and(eq(schema.accounts.userId, session.user.id), eq(schema.accounts.providerId, 'bitbucket')),
  });

  if (existing) {
    await db.update(schema.accounts)
      .set({ accessToken: tokenData.access_token, accountId: bbUser.account_id, updatedAt: new Date() })
      .where(eq(schema.accounts.id, existing.id));
  } else {
    await db.insert(schema.accounts).values({
      id: `bitbucket-${session.user.id}`,
      userId: session.user.id,
      providerId: 'bitbucket',
      accountId: bbUser.account_id,
      accessToken: tokenData.access_token,
    });
  }

  return NextResponse.redirect(`${appUrl}/?bitbucket_connected=1`);
}
