import {BaseTokenManager} from "../base/baseTokenManager.js";
import {Requester} from "../utils/requester.js";

export class InstagramTokenManager extends BaseTokenManager {

    /**
     *
     * @param clientID {string}
     * @param clientSecret {string}
     * @param usersToken {UsersToken}
     */
    constructor({clientID, clientSecret, usersToken}) {
        super(usersToken);
        this.clientID = clientID;
        this.clientSecret = clientSecret;
    }

    getOauthUrl(){
        return "https://www.instagram.com/oauth/authorize"
            + `?client_id=${this.clientID}`
            + "&redirect_uri=https://the-jailor.naaturel.be/oauth/"
            + "&scope=instagram_business_basic,instagram_business_manage_messages,instagram_business_manage_comments,"
            + "instagram_business_content_publish,instagram_business_manage_insights"
            + "&response_type=code";
    }

    async generateShortLivedToken(code){
        let headers = {
            "Content-Type": "application/x-www-form-urlencoded"
        };

        let body = {
            "client_id": this.clientID,
            "client_secret": this.clientSecret,
            "grant_type": "authorization_code",
            "redirect_uri": "https://the-jailor.naaturel.be/oauth/",
            "code": code
        };

        let encodedBody = new URLSearchParams(body);

        return await Requester.doPostRequest(
            "https://api.instagram.com/oauth/access_token", headers, encodedBody);
    }

    async generateLongLivedToken(shortLivedToken) {

        let userId = shortLivedToken.user_id;
        let shortLiveAccessToken = shortLivedToken.access_token;

        let longLiveAccessTokenData = await Requester.doGetRequest(
            "https://graph.instagram.com/access_token?grant_type=ig_exchange_token" +
            `&client_secret=${this.clientSecret}` +
            `&access_token=${shortLiveAccessToken}`);

        let accessToken = longLiveAccessTokenData.access_token;
        let expiresAt = Date.now() + longLiveAccessTokenData.expires_in*1000; //convert from sec to millis

        const result =  {
            userId : userId,
            token : accessToken,
            expiresAt : expiresAt
        };

        this.usersToken.upsert(result);

        return result;
    }

    async renew(userData){
        const data = await Requester.doGetRequest(
            "https://graph.instagram.com/refresh_access_token" +
            "?grant_type=ig_refresh_token" +
            `&access_token=${userData.token}`
        );

        let accessToken = data.access_token;
        let expiresAt = Date.now() + data.expires_in*1000; //convert from sec to millis

        const result = {
            userId : userData.userId,
            token : accessToken,
            expiresAt : expiresAt
        }

        this.usersToken.upsert(result);
        return result;
    }

}