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}/?github_error=${error}`);
  }

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

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

  // Exchange code for access token
  const tokenRes = await fetch('https://github.com/login/oauth/access_token', {
    method: 'POST',
    headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
    body: JSON.stringify({
      client_id: process.env.GITHUB_CLIENT_ID,
      client_secret: process.env.GITHUB_CLIENT_SECRET,
      code,
      redirect_uri: `${appUrl}/api/auth/github/callback`,
    }),
  });

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

  // Fetch GitHub user info
  const ghUserRes = await fetch('https://api.github.com/user', {
    headers: { Authorization: `Bearer ${tokenData.access_token}`, Accept: 'application/vnd.github+json' },
  });
  const ghUser = await ghUserRes.json();

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

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

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