/**
 * Seeds a passenger IAM user + session directly (no OTP flow) and mints an access token the portal
 * accepts. The API JwtGuard verifies the JWT signature (JWT_ACCESS_TOKEN_SECRET) and looks up the
 * session by its `id` claim; the portal then calls /auth/profile which needs a Passenger row linked
 * by iamUserId. Returns { token, profile } for the Playwright passenger storageState.
 *
 * Run standalone to validate: `npx ts-node test/fixtures/seed-passenger-session.ts` (prints the
 * token and the /auth/profile status via the running API on :4000).
 */
import { PrismaClient } from "@prisma/client";
import { SignJWT } from "jose";
import { UI_IDS } from "./seed-ui";

export const PASSENGER_USER_ID = "11111111-0000-4000-8000-000000000001";
export const PASSENGER_SESSION_ID = "11111111-0000-4000-8000-000000000002";
const EMAIL = "test.passenger@edr.local";
const USERNAME = "test_passenger";

export async function seedPassengerSession(prisma: PrismaClient): Promise<{ token: string }> {
  const secret = process.env.JWT_ACCESS_TOKEN_SECRET;
  if (!secret) throw new Error("JWT_ACCESS_TOKEN_SECRET is required to mint the passenger token");

  const userInfo = {
    id: PASSENGER_USER_ID,
    name: { en: "Test Passenger" },
    email: EMAIL,
    roles: [] as unknown[],
    status: "accepted",
    employee: [] as unknown[],
    userType: "individual",
    username: USERNAME,
    permissions: [] as unknown[],
  };
  const expiry = new Date(Date.now() + 7 * 86400_000);

  // iam.users (delete-then-insert so re-seeding is idempotent).
  await prisma.$executeRawUnsafe(`DELETE FROM iam.sessions WHERE id = $1::uuid`, PASSENGER_SESSION_ID);
  await prisma.$executeRawUnsafe(`DELETE FROM iam.users WHERE id = $1::uuid`, PASSENGER_USER_ID);
  await prisma.$executeRawUnsafe(
    `INSERT INTO iam.users (created_at, id, name, username, email, user_type, status, is_active, has_set_password, is_phone_number_verified, verified_by)
     VALUES (now(), $1::uuid, $2::jsonb, $3, $4, 'individual', 'accepted', true, true, true, 'SYSTEM')`,
    PASSENGER_USER_ID,
    JSON.stringify(userInfo.name),
    USERNAME,
    EMAIL,
  );
  await prisma.$executeRawUnsafe(
    `INSERT INTO iam.sessions (created_at, id, email, device, "userInfo", expiry_time, refresh_count, status, user_id)
     VALUES (now(), $1::uuid, $2, 'e2e', $3::jsonb, $4, 0, 'ACTIVE', $5::uuid)`,
    PASSENGER_SESSION_ID,
    EMAIL,
    JSON.stringify(userInfo),
    expiry,
    PASSENGER_USER_ID,
  );

  // Link the seeded Passenger row to this IAM user so /auth/profile resolves.
  await prisma.passenger.update({
    where: { id: UI_IDS.passenger },
    data: { iamUserId: PASSENGER_USER_ID },
  });

  const token = await new SignJWT({ id: PASSENGER_SESSION_ID })
    .setProtectedHeader({ alg: "HS256", typ: "JWT" })
    .setIssuedAt()
    .setExpirationTime("7d")
    .sign(new TextEncoder().encode(secret));

  return { token };
}

if (require.main === module) {
  (async () => {
    const prisma = new PrismaClient();
    try {
      const { token } = await seedPassengerSession(prisma);
      const api = process.env.API_URL ?? "http://localhost:4000";
      const res = await fetch(`${api}/auth/profile`, {
        headers: { Authorization: `Bearer ${token}` },
      });
      // eslint-disable-next-line no-console
      console.log(`[passenger-session] /auth/profile -> HTTP ${res.status}`);
      // eslint-disable-next-line no-console
      console.log((await res.text()).slice(0, 400));
    } finally {
      await prisma.$disconnect();
    }
  })();
}
