import { Prompt } from "../prompt.js";
import * as security from "../../utils/security.js";
import { Config } from "../../config.js";

export class CreatePasswordPrompt extends Prompt {
    //
    promptText = ["Enter a password"];

    //
    // Let the client know that we're asking for a password
    // so it can set <input type="password">
    promptOptions = { password: true };

    get player() {
        return this.scene.player;
    }

    onReply(text) {
        //
        // Check of the password is sane. This is both bad from a security point
        // of view, and technically not necessary as insane passwords couldn't
        // reside in the player lists. However, let's save some CPU cycles on
        // not hashing an insane password 1000+ times.
        // This is technically bad practice, but since this is just a game,
        // do it anyway.
        if (!security.isPasswordSane(text)) {
            this.sendError("Insane password");
            this.execute();
            return;
        }

        //
        // Block users who enter bad passwords too many times.
        if (this.player.failedPasswordsSinceLastLogin > Config.maxFailedLogins) {
            this.blockedUntil = Date.now() + Config.accountLockoutSeconds;
            this.calamity("You have been locked out for too many failed password attempts, come back later");
            return;
        }

        //
        // Handle blocked users.
        // They don't even get to have their password verified.
        if (this.player.blockedUntil > Date.now()) {
            //
            // Try to re-login too soon, and your lockout lasts longer.
            this.blockedUntil += Config.accountLockoutSeconds;
            this.calamity("You have been locked out for too many failed password attempts, come back later");
            return;
        }

        //
        // Verify the password against the hash we've stored.
        if (!security.verifyPassword(text, this.player.passwordHash)) {
            this.sendError("Incorrect password!");
            this.player.failedPasswordsSinceLastLogin++;

            this.session.sendDebug(`Failed login attempt #${this.player.failedPasswordsSinceLastLogin}`);
            this.execute();

            return;
        }

        this.player.lastSucessfulLoginAt = new Date();
        this.player.failedPasswordsSinceLastLogin = 0;

        //
        // We do not allow a player to be logged in more than once!
        if (this.player.loggedIn) {
            this.calamity("This player is already logged in");
            return;
        }

        this.scene.passwordAccepted();

        //
        // Password was correct, go to main game
        this.session.setState(new JustLoggedInState(this.session));
    }
}
