import { env } from "../config/env.js";
import { prisma } from "../db/prisma.js";
import { hashAdminPassword } from "../modules/admin/admin-auth.service.js";

/**
 * Creates the first (or an additional) `AdminUser` for the admin
 * application — there is no self-service admin signup, on purpose (see the
 * `AdminUser` model doc comment in schema.prisma).
 *
 *   pnpm --filter api exec tsx src/scripts/create-admin.ts \
 *     --email=ops@example.com --password='...' --name='Ops'
 *
 * Each flag falls back to the matching `ADMIN_INITIAL_*` env var when
 * omitted, so a deployment can bake the first admin's credentials into its
 * environment and run this once from the container without passing args.
 * Refuses (exit 1) if an `AdminUser` with that email already exists —
 * changing an existing admin's password is a manual DB operation for now,
 * not something this script does.
 */
function flag(name: string): string | undefined {
  const prefix = `--${name}=`;
  const arg = process.argv.find((value) => value.startsWith(prefix));
  return arg === undefined ? undefined : arg.slice(prefix.length);
}

async function createAdmin(): Promise<void> {
  const email = (flag("email") ?? env.ADMIN_INITIAL_EMAIL)?.trim().toLowerCase();
  const password = flag("password") ?? env.ADMIN_INITIAL_PASSWORD;
  const name = (flag("name") ?? env.ADMIN_INITIAL_NAME)?.trim();

  if (!email || !password || !name) {
    throw new Error(
      "Missing required input. Provide --email, --password and --name (or set ADMIN_INITIAL_EMAIL / ADMIN_INITIAL_PASSWORD / ADMIN_INITIAL_NAME).",
    );
  }
  if (password.length < 8) {
    throw new Error("Password must be at least 8 characters.");
  }

  const existing = await prisma.adminUser.findUnique({ where: { email } });
  if (existing) {
    throw new Error(`An admin with email "${email}" already exists (id ${existing.id}).`);
  }

  const passwordHash = await hashAdminPassword(password);
  const admin = await prisma.adminUser.create({ data: { email, name, passwordHash } });
  console.info(`Created admin #${admin.id} <${admin.email}> ("${admin.name}").`);
}

createAdmin()
  .then(() => prisma.$disconnect())
  .catch(async (err) => {
    console.error(err instanceof Error ? err.message : err);
    await prisma.$disconnect();
    process.exit(1);
  });
