import { getLogger } from "@/logger";
import { GitHubAuthProvider, inviteToGitHub } from "@/auth/github";
import {
  AuthState,
  authTicketOAuth,
  getAuthState,
  getCode,
  getUser
} from "@/auth/auth";

const logger = getLogger("/oauth/github/redirect");

export async function GET(request: Request) {
  const code = await getCode(request);
  if (code instanceof Response) return code;

  const tokenBody = await GitHubAuthProvider.getToken(code);
  if (tokenBody == null) throw "baby";

  const provider = new GitHubAuthProvider(tokenBody.access_token);
  const id = await provider.getId();
  const permitted = await provider.isPermitted();

  // If someone clicked register on the front page with an existing account,
  // wire it to their user via the auth ticket
  let gluestickId = null;
  const authState = await getAuthState();
  if (authState === AuthState.LoggedIn) {
    const currentUser = await getUser();
    gluestickId = currentUser!.id;
  }

  if (!permitted && gluestickId == null) {
    logger.info({ id }, "user tried to sign up");
    return new Response("not permitted to register account", { status: 403 });
  }

  const userId = await GitHubAuthProvider.update(
    id,
    tokenBody.access_token,
    gluestickId ?? undefined
  );

  if (gluestickId != null) {
    await inviteToGitHub(provider);
    return new Response(null, {
      status: 302,
      headers: {
        Location: "/me"
      }
    });
  }

  const [user, authTicket] = await authTicketOAuth(userId);

  if (user?.username !== null) {
    return new Response(null, {
      status: 302,
      headers: {
        "Set-Cookie": `ticket=${authTicket.ticket}; Path=/;`,
        Location: "/me"
      }
    });
  }

  const username = await provider.getDisplayName();
  const email = await provider.getEmail();
  const avatarUrl = await provider.getAvatar();

  const query = new URLSearchParams();
  query.append("username", username);
  query.append("email", email ?? "");
  query.append("avatar", avatarUrl ?? "");

  return new Response(null, {
    status: 302,
    headers: {
      "Set-Cookie": `ticket=${authTicket.ticket}; Path=/;`,
      Location: "/register?" + query.toString()
    }
  });
}
