import { describe, it, expect, vi, beforeEach } from "vitest";

/**
 * Offline-Tests für die Mapping-Logik der Detail-Queries. Die Drizzle-DB wird
 * gemockt (kein Postgres in der Sandbox), sodass wir das reine Verhalten
 * verifizieren: „im Gerätehaus" (vehicleId null) -> `fahrzeug: null`, sonst
 * verlinktes Fahrzeug; sowie not-found (-> null) bei fehlendem Datensatz.
 *
 * Wir mocken `@/db` als verkettbaren Query-Builder, dessen letzte Stufe
 * (`limit`/`orderBy`/`where`) ein vorab gesetztes Ergebnis-Array liefert.
 */

type Rows = unknown[];
let queue: Rows[];

function nextRows(): Rows {
  return queue.length > 0 ? (queue.shift() as Rows) : [];
}

// Ein Thenable-Builder: jede Methode gibt sich selbst zurück; `await` löst die
// nächste Ergebnismenge auf. So funktionieren sowohl `await db.select()....limit()`
// als auch `await db.select()....orderBy()`.
function makeBuilder(): Record<string, unknown> {
  const builder: Record<string, unknown> = {};
  const chain = () => builder;
  for (const m of [
    "select",
    "from",
    "innerJoin",
    "leftJoin",
    "where",
    "limit",
    "orderBy",
  ]) {
    builder[m] = vi.fn(chain);
  }
  builder.then = (resolve: (v: Rows) => unknown) => resolve(nextRows());
  return builder;
}

vi.mock("@/db", () => ({
  db: {
    select: () => makeBuilder(),
  },
}));

const { getGeraetDetail } = await import("@/lib/detail/queries");

const WEHR = {
  id: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
  name: "FF Test",
  art: "FF",
  strasse: null,
  plz: null,
  ort: null,
  wehrfuehrer: null,
  telefon: null,
  email: null,
};

beforeEach(() => {
  queue = [];
});

describe("getGeraetDetail", () => {
  it("liefert null, wenn das Gerät nicht existiert", async () => {
    queue = [[]]; // erste Query (Gerät) leer
    const out = await getGeraetDetail("00000000-0000-0000-0000-000000000000");
    expect(out).toBeNull();
  });

  it("ohne Fahrzeug-Zuordnung -> fahrzeug = null (im Gerätehaus)", async () => {
    queue = [
      [
        {
          id: "g1",
          brigadeId: WEHR.id,
          name: "Strahlrohr",
          status: "einsatzbereit",
          kategorie: "Armaturen",
          vehicleId: null,
          vehicleName: null,
        },
      ],
      [], // loadMerkmalRows
      [WEHR], // getBrigadeCard
    ];
    const out = await getGeraetDetail("g1");
    expect(out?.fahrzeug).toBeNull();
    expect(out?.kategorie).toBe("Armaturen");
  });

  it("mit Fahrzeug-Zuordnung -> verlinktes Fahrzeug", async () => {
    queue = [
      [
        {
          id: "g1",
          brigadeId: WEHR.id,
          name: "Strahlrohr",
          status: "einsatzbereit",
          kategorie: "Armaturen",
          vehicleId: "v1",
          vehicleName: "TLFA 4000",
        },
      ],
      [],
      [WEHR],
    ];
    const out = await getGeraetDetail("g1");
    expect(out?.fahrzeug).toEqual({ id: "v1", name: "TLFA 4000" });
  });
});
