var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { decodeJWTPayload, isExpiredJWT } from '../utils';
export class User {
    constructor(Api, info, idToken, refreshToken) {
        this.Api = Api;
        this.idToken = idToken;
        this.refreshToken = refreshToken;
        this.setInfo(info);
    }
    setInfo(info) {
        const { uid, providerId, email, emailVerified, createdAt, lastLogin, username, phoneNumber, displayName, photoURL, bio, url, address, additionalData, claims, settings, isAnonymous, isNewUser, } = info;
        this.uid = uid;
        this.providerId = providerId;
        this.email = email;
        this.emailVerified = emailVerified;
        this.createdAt = createdAt;
        this.lastLogin = lastLogin;
        this.username = username;
        this.displayName = displayName;
        this.phoneNumber = phoneNumber;
        this.photoURL = photoURL;
        this.bio = bio;
        this.url = url;
        this.address = address;
        this.additionalData = additionalData;
        this.claims = claims;
        this.settings = settings;
        this.isAnonymous = isAnonymous;
        this.isNewUser = isNewUser;
        return info;
    }
    toJSON() {
        const uid = this.uid;
        const providerId = this.providerId;
        const email = this.email;
        const emailVerified = this.emailVerified;
        const createdAt = this.createdAt;
        const lastLogin = this.lastLogin;
        const username = this.username;
        const phoneNumber = this.phoneNumber;
        const displayName = this.displayName;
        const photoURL = this.photoURL;
        const bio = this.bio;
        const url = this.url;
        const address = this.address;
        const additionalData = this.additionalData;
        const claims = this.claims;
        const settings = this.settings;
        const isAnonymous = this.isAnonymous;
        const isNewUser = this.isNewUser;
        return {
            uid,
            providerId,
            email,
            emailVerified,
            createdAt,
            lastLogin,
            username,
            phoneNumber,
            displayName,
            photoURL,
            bio,
            url,
            address,
            additionalData,
            claims,
            settings,
            isAnonymous,
            isNewUser,
        };
    }
    getIdToken(forceRefresh = false) {
        return __awaiter(this, void 0, void 0, function* () {
            // renew
            if (isExpiredJWT(this.idToken) || forceRefresh) {
                const { idToken } = yield this.Api.get('/token', {
                    refreshToken: this.refreshToken,
                });
                this.idToken = idToken;
            }
            return this.idToken;
        });
    }
    getIdTokenResult(forceRefresh = false) {
        return __awaiter(this, void 0, void 0, function* () {
            const idToken = yield this.getIdToken(forceRefresh);
            return decodeJWTPayload(idToken);
        });
    }
    sendEmailVerification() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.emailVerified) {
                return yield this.Api.put('/oob', {}, {
                    mode: 'verifyEmail',
                    email: this.email,
                });
            }
        });
    }
    updateProfile(profile) {
        return __awaiter(this, void 0, void 0, function* () {
            const newInfo = yield this.Api.post('/user', {}, {
                profile,
            });
            return this.setInfo(newInfo);
        });
    }
    setAdditionalData(data) {
        return __awaiter(this, void 0, void 0, function* () {
            const newInfo = yield this.Api.post('/user/additional', {}, {
                additionalData: data,
            });
            return this.setInfo(newInfo);
        });
    }
    setSettings(data) {
        return __awaiter(this, void 0, void 0, function* () {
            const newInfo = yield this.Api.post('/user/settings', {}, {
                settings: data,
            });
            return this.setInfo(newInfo);
        });
    }
    setProfilePublicly(props) {
        return __awaiter(this, void 0, void 0, function* () {
            const newInfo = yield this.Api.post('/user/publicly', {}, {
                publicly: props,
            });
            return this.setInfo(newInfo);
        });
    }
    setProfilePrivately(props) {
        return __awaiter(this, void 0, void 0, function* () {
            const newInfo = yield this.Api.post('/user/privately', {}, {
                privately: props,
            });
            return this.setInfo(newInfo);
        });
    }
    setUsername(username) {
        return __awaiter(this, void 0, void 0, function* () {
            const newInfo = yield this.Api.post('/user/username', {}, {
                username,
            });
            return this.setInfo(newInfo);
        });
    }
    changePassword(currentPassword, newPassword) {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.Api.post('/user/password', {}, {
                currentPassword,
                newPassword,
            });
        });
    }
    logout() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.Api.delete('/');
        });
    }
    delete() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.Api.delete('/cancel', {}, {
                refreshToken: this.refreshToken,
            });
        });
    }
}
