/**
 * Notfall-Reset: setzt das Passwort eines Mitarbeiter-Users direkt in der DB.
 * Wird vom scripts/admin-rescue.sh-Wrapper im Container ausgeführt, wenn ein
 * Admin sich ausgesperrt hat (z.B. weil admin@admin.com keine echte
 * E-Mail-Adresse ist und der Passwort-vergessen-Flow daher nicht greift).
 *
 * Aufruf:
 *   npx tsx prisma/reset-admin-password.ts <email>            # generiert PW
 *   npx tsx prisma/reset-admin-password.ts <email> <passwort> # eigenes PW
 *
 * Setzt zusätzlich `tokenInvalidatedAt = now()` → alle bestehenden Sessions
 * dieses Users werden sofort ausgeloggt (Defense gegen Wiederverwendung
 * gestohlener Tokens).
 */
import bcrypt from 'bcryptjs';
import prisma from '../src/lib/prisma.js';
import { validatePasswordComplexity, STAFF_MIN_PASSWORD_LENGTH } from '../src/utils/passwordGenerator.js';

const BCRYPT_COST = 12;

function generateRescuePassword(): string {
  const upper = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
  const lower = 'abcdefghijkmnopqrstuvwxyz';
  const digits = '23456789';
  const special = '!@#$%&*+=?';
  const all = upper + lower + digits + special;
  const pick = (s: string) => s[Math.floor(Math.random() * s.length)];
  const chars = [pick(upper), pick(lower), pick(digits), pick(special)];
  for (let i = chars.length; i < 28; i++) chars.push(pick(all));
  for (let i = chars.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [chars[i], chars[j]] = [chars[j], chars[i]];
  }
  return chars.join('');
}

async function main() {
  const email = process.argv[2];
  const providedPw = process.argv[3];

  if (!email) {
    console.error('Aufruf: npx tsx prisma/reset-admin-password.ts <email> [passwort]');
    process.exit(1);
  }

  const user = await prisma.user.findUnique({
    where: { email },
    select: { id: true, email: true, firstName: true, lastName: true },
  });
  if (!user) {
    console.error(`User "${email}" nicht gefunden.`);
    process.exit(2);
  }

  let plain: string;
  if (providedPw) {
    const c = validatePasswordComplexity(providedPw, { minLength: STAFF_MIN_PASSWORD_LENGTH });
    if (!c.ok) {
      console.error('Übergebenes Passwort erfüllt Mitarbeiter-Komplexität nicht:');
      for (const e of c.errors) console.error('  - ' + e);
      process.exit(3);
    }
    plain = providedPw;
  } else {
    plain = generateRescuePassword();
  }

  const hash = await bcrypt.hash(plain, BCRYPT_COST);
  await prisma.user.update({
    where: { id: user.id },
    data: {
      password: hash,
      passwordResetToken: null,
      passwordResetExpiresAt: null,
      tokenInvalidatedAt: new Date(),
    },
  });

  console.log('========================================================');
  console.log(`  User: ${user.email} (${user.firstName} ${user.lastName})`);
  console.log(`  Neues Passwort: ${plain}`);
  console.log('  ⚠️  Wird hier EINMAL ausgegeben – sofort kopieren!');
  console.log('  Alle bestehenden Sessions wurden invalidiert.');
  console.log('========================================================');
}

main()
  .catch((e) => {
    console.error('Reset fehlgeschlagen:', e);
    process.exit(99);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
