import DiscordOauth2 from 'discord-oauth2';
import {User} from "../models/User";

const oauth = new DiscordOauth2();

/**
 * Retrieves an access & refresh token from the discord api
 * @param code The authorization code from the callback
 */
export const createTokenByCode = (code: string) => oauth.tokenRequest({
    grantType: "authorization_code",
    scope: "identify guilds",
    clientId: process.env.DC_CLIENT,
    clientSecret: process.env.DC_SECRET,
    redirectUri: process.env.DC_REDIRECT_URI,
    code
});

/**
 * Generate a new access token from the refresh token
 * @param refreshToken The token to refresh the access token
 */
export const generateToken = (refreshToken: string) => oauth.tokenRequest({
    grantType: "refresh_token",
    scope: "identify guilds",
    clientId: process.env.DC_CLIENT,
    clientSecret: process.env.DC_SECRET,
    redirectUri: process.env.DC_REDIRECT_URI,
    refreshToken
});

/**
 * Gets the guilds from the access token.
 * This function also automatically renews the access token if it expires
 * @param refreshDate The date of when to renew the provided access token
 * @param refreshToken The token to refresh the access token
 * @param accessToken The token to access the discord api
 */
export const getGuilds = async (refreshDate: Date, refreshToken: string, accessToken: string) => {
    let token = accessToken;
    if (refreshDate.valueOf() < Date.now()) {
        const newToken = await generateToken(refreshToken);
        token = newToken.access_token;
        User.update({accessToken: token, refreshDate: new Date(Date.now() + newToken.expires_in),
            refreshToken: newToken.refresh_token}, {where: {refreshToken: refreshToken}});
    }
    return await oauth.getUserGuilds(token);
}

/**
 * Gets user information from the discord api
 * @param token The access token of the user
 */
export const getUser = (token: string) => oauth.getUser(token);