import { redirect } from 'next/navigation';
import type { NextRequest } from 'next/server';

import { createAccountsApi } from '@/packages/features/accounts/src/server/api';

import { pathsConfig } from '@kit/shared/config';
import {
  createAuthCallbackService,
  getErrorURLParameters,
} from '@kit/supabase/auth';
import { getSupabaseServerClient } from '@kit/supabase/server-client';

const ERROR_PATH = '/auth/callback/error';

const redirectOnError = (searchParams?: string) => {
  return redirect(`${ERROR_PATH}${searchParams ? `?${searchParams}` : ''}`);
};

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);

  const error = searchParams.get('error');
  if (error) {
    const { searchParams } = getErrorURLParameters({ error });
    return redirectOnError(searchParams);
  }

  const authCode = searchParams.get('code');
  if (!authCode) {
    return redirectOnError();
  }

  let redirectPath = searchParams.get('next') || pathsConfig.app.home;
  // if we have an invite token, we redirect to the join team page
  // instead of the default next url. This is because the user is trying
  // to join a team and we want to make sure they are redirected to the
  // correct page.
  const inviteToken = searchParams.get('invite_token');
  if (inviteToken) {
    const urlParams = new URLSearchParams({
      invite_token: inviteToken,
      email: searchParams.get('email') ?? '',
    });

    redirectPath = `${pathsConfig.app.joinTeam}?${urlParams.toString()}`;
  }

  const service = createAuthCallbackService(getSupabaseServerClient());
  const oauthResult = await service.exchangeCodeForSession(authCode);
  if (!('isSuccess' in oauthResult)) {
    return redirectOnError(oauthResult.searchParams);
  }

  const api = createAccountsApi(getSupabaseServerClient());

  const account = await api.getPersonalAccountByUserId(oauthResult.user.id);

  if (!account.email || !account.name || !account.last_name) {
    return redirect(pathsConfig.auth.updateAccount);
  }

  return redirect(redirectPath);
}
