import { describe, it, expect } from "vitest";
import {
  vehicleBaseSchema,
  vehicleStatusSchema,
  buildMerkmalValuesSchema,
} from "../vehicle";
import type { MerkmalDefinition } from "@/lib/merkmale/types";

const def = (over: Partial<MerkmalDefinition>): MerkmalDefinition => ({
  merkmalId: "11111111-1111-1111-1111-111111111111",
  name: "Merkmal",
  typ: "text",
  einheit: null,
  pflicht: false,
  reihenfolge: 0,
  optionen: [],
  vorgabeNum: null,
  vorgabeText: null,
  vorgabeBool: null,
  ...over,
});

describe("vehicleBaseSchema", () => {
  it("verlangt einen Namen", () => {
    const r = vehicleBaseSchema.safeParse({ name: "", funkrufname: "", notiz: "" });
    expect(r.success).toBe(false);
  });

  it("akzeptiert Name mit leeren Optionalfeldern (-> undefined)", () => {
    const r = vehicleBaseSchema.safeParse({
      name: "HLF 2 Musterdorf",
      funkrufname: "",
      notiz: "",
      templateId: "",
    });
    expect(r.success).toBe(true);
    if (r.success) {
      expect(r.data.funkrufname).toBeUndefined();
      expect(r.data.templateId).toBeUndefined();
    }
  });

  it("akzeptiert eine gültige templateId (uuid)", () => {
    const r = vehicleBaseSchema.safeParse({
      name: "HLF 2",
      templateId: "22222222-2222-2222-2222-222222222222",
    });
    expect(r.success).toBe(true);
  });
});

describe("vehicleStatusSchema", () => {
  it("akzeptiert nur asset_status-Werte", () => {
    expect(vehicleStatusSchema.safeParse({ id: "33333333-3333-3333-3333-333333333333", status: "wartung" }).success).toBe(true);
    expect(vehicleStatusSchema.safeParse({ id: "33333333-3333-3333-3333-333333333333", status: "kaputt" }).success).toBe(false);
  });
});

describe("buildMerkmalValuesSchema", () => {
  it("validiert number-Merkmale typgerecht und coerced Strings", () => {
    const schema = buildMerkmalValuesSchema([
      def({ typ: "number", name: "Löschwassertank", einheit: "l" }),
    ]);
    const r = schema.safeParse([
      { merkmalId: def({}).merkmalId, num: "2000" },
    ]);
    expect(r.success).toBe(true);
    if (r.success) expect(r.data[0]?.num).toBe(2000);
  });

  it("lehnt nicht-numerische Eingabe für number ab", () => {
    const schema = buildMerkmalValuesSchema([def({ typ: "number" })]);
    const r = schema.safeParse([{ merkmalId: def({}).merkmalId, num: "abc" }]);
    expect(r.success).toBe(false);
  });

  it("erzwingt Pflichtmerkmale (number ohne Wert -> Fehler)", () => {
    const schema = buildMerkmalValuesSchema([def({ typ: "number", pflicht: true })]);
    const r = schema.safeParse([{ merkmalId: def({}).merkmalId, num: null }]);
    expect(r.success).toBe(false);
  });

  it("erlaubt optionale Merkmale ohne Wert", () => {
    const schema = buildMerkmalValuesSchema([def({ typ: "number", pflicht: false })]);
    const r = schema.safeParse([{ merkmalId: def({}).merkmalId, num: null }]);
    expect(r.success).toBe(true);
  });

  it("beschränkt enum-Werte auf erlaubte Optionen", () => {
    const schema = buildMerkmalValuesSchema([
      def({ typ: "enum", optionen: [{ wert: "TS", label: "Tragkraftspritze" }] }),
    ]);
    expect(schema.safeParse([{ merkmalId: def({}).merkmalId, text: "TS" }]).success).toBe(true);
    expect(schema.safeParse([{ merkmalId: def({}).merkmalId, text: "XX" }]).success).toBe(false);
  });

  it("coerced boolean-Merkmale", () => {
    const schema = buildMerkmalValuesSchema([def({ typ: "boolean", name: "Allradantrieb" })]);
    const r = schema.safeParse([{ merkmalId: def({}).merkmalId, bool: true }]);
    expect(r.success).toBe(true);
    if (r.success) expect(r.data[0]?.bool).toBe(true);
  });

  it("ignoriert Werte zu unbekannten Merkmalen (nur erlaubte merkmalIds)", () => {
    const schema = buildMerkmalValuesSchema([def({ typ: "text" })]);
    const r = schema.safeParse([
      { merkmalId: "99999999-9999-9999-9999-999999999999", text: "hallo" },
    ]);
    expect(r.success).toBe(false);
  });

  it("erzwingt Pflichtmerkmale auch bei vollständiger Auslassung (leeres Array)", () => {
    const schema = buildMerkmalValuesSchema([
      def({ typ: "number", pflicht: true, name: "Löschwassertank" }),
    ]);
    // Pflichtmerkmal fehlt komplett -> Validierung muss greifen (nicht trauen).
    expect(schema.safeParse([]).success).toBe(false);
  });

  it("erzwingt fehlende Pflichtmerkmale bei teilweise befülltem Array", () => {
    const idA = "11111111-1111-1111-1111-11111111aaaa";
    const idB = "11111111-1111-1111-1111-11111111bbbb";
    const schema = buildMerkmalValuesSchema([
      def({ merkmalId: idA, typ: "text", pflicht: true, name: "A" }),
      def({ merkmalId: idB, typ: "boolean", pflicht: true, name: "B" }),
    ]);
    // Nur A geliefert, Pflicht-B fehlt komplett.
    const r = schema.safeParse([{ merkmalId: idA, text: "x" }]);
    expect(r.success).toBe(false);
  });

  it("akzeptiert ein leeres Array, wenn keine Pflichtmerkmale definiert sind", () => {
    const schema = buildMerkmalValuesSchema([def({ typ: "text", pflicht: false })]);
    expect(schema.safeParse([]).success).toBe(true);
  });

  it("akzeptiert vollständig gesetzte Pflichtmerkmale", () => {
    const idA = "11111111-1111-1111-1111-11111111aaaa";
    const schema = buildMerkmalValuesSchema([
      def({ merkmalId: idA, typ: "text", pflicht: true, name: "A" }),
    ]);
    expect(schema.safeParse([{ merkmalId: idA, text: "x" }]).success).toBe(true);
  });

  it("lehnt ein vorhandenes, aber leeres Pflichtmerkmal weiterhin ab", () => {
    const idA = "11111111-1111-1111-1111-11111111aaaa";
    const schema = buildMerkmalValuesSchema([
      def({ merkmalId: idA, typ: "text", pflicht: true, name: "A" }),
    ]);
    expect(schema.safeParse([{ merkmalId: idA, text: "" }]).success).toBe(false);
  });
});
