import { Email as GiteaEmail, User } from "gitea-js";
import { OAuthConfig, OAuthUserConfig } from "next-auth/providers";

export interface GiteaProfile extends User {
  username?: string;
}

export default function Gitea(
  config: OAuthUserConfig<GiteaProfile> & {
    enterprise?: {
      baseUrl?: string;
    };
  }
): OAuthConfig<GiteaProfile> {
  const baseUrl = config?.enterprise?.baseUrl ?? "https://gitea.com";
  const apiBaseUrl = config?.enterprise?.baseUrl
    ? `${config?.enterprise?.baseUrl}/api/v1`
    : "https://gitea.com/api/v1";

  return {
    id: "gitea",
    name: "Gitea",
    type: "oauth",
    authorization: {
      url: `${baseUrl}/login/oauth/authorize`,
      params: { scope: "read:user user:email" },
    },
    token: `${baseUrl}/login/oauth/access_token`,
    userinfo: {
      url: `${apiBaseUrl}/user`,
      async request({
        tokens,
        provider,
      }: {
        tokens: { access_token: string };
        provider: OAuthConfig<GiteaProfile>;
      }) {
        const profile = await fetch(provider.userinfo?.url as URL, {
          headers: {
            Authorization: `Bearer ${tokens.access_token}`,
            "User-Agent": "authjs",
          },
        }).then(async (res) => await res.json());

        if (!profile.email) {
          const res = await fetch(`${apiBaseUrl}/user/emails`, {
            headers: {
              Authorization: `Bearer ${tokens.access_token}`,
              "User-Agent": "authjs",
            },
          });

          if (res.ok) {
            const emails: GiteaEmail[] = await res.json();
            profile.email = (emails.find((e) => e.primary) ?? emails[0]).email;
          }
        }

        return profile;
      },
    },
    profile(profile) {
      return {
        id: profile.id?.toString(),
        name: profile.username ?? profile.login,
        email: profile.email,
        image: profile.avatar_url,
      };
    },
    style: {
      logo: "/gitea.svg",
      brandColor: "#609926",
    },
    options: config,
  };
}
