import { parseArgs } from "node:util";
import { createInterface } from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";
import { eq, isNotNull } from "drizzle-orm";
import { db, runMigrations } from "../db/client.js";
import { refreshTokens, users } from "../db/schema.js";
import { hashPassword } from "../auth/passwords.js";
const MIN_PASSWORD_LENGTH = 8;
/**
 * `private-server reset-admin-password [--email <email>] [--password <mdp>]`
 *
 * Réinitialise le mot de passe d'un compte administrateur oublié et révoque
 * tous ses refresh tokens (déconnexion forcée de tous les appareils).
 *
 * Sans --email : cible le compte si un seul possède un mot de passe,
 * sinon demande l'email en interactif. Sans --password : saisie interactive.
 */
export async function runResetAdminPassword(argv) {
    const parsed = parseArgs({
        args: argv,
        options: {
            email: { type: "string" },
            password: { type: "string" },
        },
        allowPositionals: false,
        strict: true,
    });
    runMigrations();
    let email = parsed.values.email;
    let password = parsed.values.password;
    // Cible par défaut : seul compte avec mot de passe.
    if (!email) {
        const candidates = db
            .select({ id: users.id, email: users.email })
            .from(users)
            .where(isNotNull(users.passwordHash))
            .all();
        if (candidates.length === 0) {
            throw new Error("Aucun compte avec mot de passe. Créez un compte via /auth/register d'abord.");
        }
        if (candidates.length === 1) {
            email = candidates[0].email ?? candidates[0].id;
            console.log(`Compte ciblé : ${email}`);
        }
    }
    const rl = createInterface({ input, output });
    try {
        if (!email) {
            email = (await rl.question("Email du compte à réinitialiser : ")).trim();
        }
        if (!password) {
            // eslint-disable-next-line no-constant-condition
            while (true) {
                password = await rl.question(`Nouveau mot de passe (min ${MIN_PASSWORD_LENGTH} caractères) : `);
                if (password.length >= MIN_PASSWORD_LENGTH)
                    break;
                console.error(`Trop court — minimum ${MIN_PASSWORD_LENGTH} caractères.`);
            }
        }
        if (password.length < MIN_PASSWORD_LENGTH) {
            throw new Error(`Mot de passe trop court — minimum ${MIN_PASSWORD_LENGTH} caractères.`);
        }
        const user = db.select().from(users).where(eq(users.email, email)).limit(1).get();
        if (!user) {
            throw new Error(`Aucun compte avec l'email "${email}".`);
        }
        const passwordHash = hashPassword(password);
        db.transaction((tx) => {
            tx.update(users).set({ passwordHash }).where(eq(users.id, user.id)).run();
            // Révocation de tous les refresh tokens → déconnexion de tous les appareils.
            tx.update(refreshTokens)
                .set({ revokedAt: new Date() })
                .where(eq(refreshTokens.userId, user.id))
                .run();
        });
        console.log(`Mot de passe réinitialisé pour ${email} — tous les appareils sont déconnectés.`);
    }
    finally {
        rl.close();
    }
}
//# sourceMappingURL=reset-admin-password.js.map