import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import { eq } from "drizzle-orm";
import { hash } from "@node-rs/argon2";
import * as schema from "../src/db/schema/index.js";

/**
 * Seed für Auth-Erstkonten (idempotent — mehrfaches Ausführen ändert keine
 * Counts; Querschnittsstandard 7).
 *
 * - 1 platform_admin (authTyp `authentik`, brigadeId = NULL). Muss zusätzlich
 *   in Authentik existieren; der signIn-Callback verweigert sonst (Henne-Ei
 *   beim Erst-Deploy, siehe Plan, Risiken Punkt 7).
 * - 1 Demo-Wehr + 1 wehr_admin (authTyp `local`, argon2id-Passworthash).
 *
 * Liest `DATABASE_URL` direkt aus der Umgebung (keine Next.js-Env-Validierung).
 */
const ARGON2_PARAMS = {
  type: 2 as const,
  memoryCost: 19456,
  timeCost: 2,
  parallelism: 1,
};

const PLATFORM_ADMIN_EMAIL =
  process.env.SEED_PLATFORM_ADMIN_EMAIL ?? "admin@floriannetz.local";
const WEHR_ADMIN_EMAIL =
  process.env.SEED_WEHR_ADMIN_EMAIL ?? "wehr-admin@floriannetz.local";
const WEHR_ADMIN_PASSWORD =
  process.env.SEED_WEHR_ADMIN_PASSWORD ?? "florian-netz-demo";
const DEMO_BRIGADE_NAME =
  process.env.SEED_DEMO_BRIGADE_NAME ?? "FF Demo (Seed)";

async function main(): Promise<void> {
  const connectionString = process.env.DATABASE_URL;
  if (!connectionString) {
    throw new Error("DATABASE_URL ist nicht gesetzt.");
  }

  const pool = new Pool({ connectionString, max: 1 });
  const db = drizzle(pool, { schema });

  try {
    // Platform-Admin (authentik): Upsert auf E-Mail (Natural Key).
    await db
      .insert(schema.users)
      .values({
        email: PLATFORM_ADMIN_EMAIL,
        name: "Plattform-Administration",
        rolle: "platform_admin",
        authTyp: "authentik",
        brigadeId: null,
        passwortHash: null,
        aktiv: true,
      })
      .onConflictDoUpdate({
        target: schema.users.email,
        set: {
          rolle: "platform_admin",
          authTyp: "authentik",
          brigadeId: null,
          aktiv: true,
        },
      });

    // Demo-Wehr: idempotent (brigades hat keinen Natural-Key-Unique → Lookup).
    let brigade = await db.query.brigades.findFirst({
      where: eq(schema.brigades.name, DEMO_BRIGADE_NAME),
    });
    if (!brigade) {
      const [created] = await db
        .insert(schema.brigades)
        .values({ name: DEMO_BRIGADE_NAME, art: "FF" })
        .returning();
      brigade = created;
    }
    if (!brigade) throw new Error("Demo-Wehr konnte nicht angelegt werden.");

    // Wehr-Admin (local) mit argon2id-Hash: Upsert auf E-Mail.
    const passwortHash = await hash(WEHR_ADMIN_PASSWORD, ARGON2_PARAMS);
    await db
      .insert(schema.users)
      .values({
        email: WEHR_ADMIN_EMAIL,
        name: "Wehr-Administration (Demo)",
        rolle: "wehr_admin",
        authTyp: "local",
        brigadeId: brigade.id,
        passwortHash,
        aktiv: true,
      })
      .onConflictDoUpdate({
        target: schema.users.email,
        set: {
          rolle: "wehr_admin",
          authTyp: "local",
          brigadeId: brigade.id,
          passwortHash,
          aktiv: true,
        },
      });

    console.log("Auth-Seed erfolgreich (idempotent).");
    console.log(`  platform_admin (authentik): ${PLATFORM_ADMIN_EMAIL}`);
    console.log(`  wehr_admin (local):         ${WEHR_ADMIN_EMAIL}`);
  } finally {
    await pool.end();
  }
}

main().catch((err: unknown) => {
  console.error("Auth-Seed fehlgeschlagen:", err);
  process.exit(1);
});
