import axios from "axios";
import queryString from "query-string";
import { DatabaseService } from "../services/databaseService";
import { GithubOAuthOptions } from "../helpers/interface.types";

const dbService = DatabaseService.getInstance();

export const getAuthURLGithub = (options: GithubOAuthOptions): string => {
  const params = queryString.stringify({
    client_id: options.clientId,
    redirect_uri: options.redirectUri,
    client_secret: options.clientSecret,
  });
  return `https://github.com/login/oauth/authorize?${params}`;
};

export const getTokenGithub = async (code: string, options: GithubOAuthOptions): Promise<string> => {
  const response = await axios.post(
    "https://github.com/login/oauth/access_token",
    queryString.stringify({
      client_id: options.clientId,
      client_secret: options.clientSecret,
      code,
      redirect_uri: options.redirectUri,
    }),
    { headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" } }
  );

  return response.data.access_token;
};

export const getUserInfoGithub = async (accessToken: string): Promise<any> => {
  const response = await axios.get("https://api.github.com/user", {
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  return response.data;
};

export const handleGithubCallback = async (code: string, options: GithubOAuthOptions) => {
  try {
    const accessToken = await getTokenGithub(code, options);
    const profile = await getUserInfoGithub(accessToken);

    // Now update the user's GitHub ID in the database
    const user = await dbService.findUserByEmail(profile.email);
    if (user) {
      await dbService.updateUser(user.id, { githubId: profile.id.toString() });
    }
    
    return profile;
  } catch (err) {
    throw err;
  }
};
