import { describe, expect, it } from "vitest";
import { computeSallePricing } from "@shared/sallePricing";

import {
  buildReservationSallePayload,
  buildReservationSalleTitle,
  parseReservationSallePayload,
  validateReservationSalleFormInput,
} from "@/lib/reservationSalle";

describe("reservation salle helpers", () => {
  it("parses canonical reservation payload fields", () => {
    const parsed = parseReservationSallePayload(
      JSON.stringify({
        formulaireType: "reservation_salle_mjs",
        sallesIds: ["dojo"],
        motifReservation: "Atelier jeunesse",
        dateReservation: "2026-06-01",
        dateFinReservation: "2026-06-03",
        heureDebut: "09:00",
        heureFin: "17:00",
        nombreParticipants: "30",
      })
    );

    expect(parsed.selectedSalles).toEqual(["dojo"]);
    expect(parsed.formData.dateReservation).toBe("2026-06-01");
    expect(parsed.formData.dateFinReservation).toBe("2026-06-03");
    expect(parsed.formData.heureDebut).toBe("09:00");
    expect(parsed.formData.useDetailedSchedule).toBe(false);
  });

  it("recovers legacy salle payload fields", () => {
    const parsed = parseReservationSallePayload(
      JSON.stringify({
        titre: "Réservation Salle IBIS, Hall-Amphithéâtre - 24/04/2026",
        description: "sport",
        dateSouhaitee: "2026-05-21",
        "heureDébut": "09:45",
        "heureFin": "23:50",
        nombreParticipants: "25",
      })
    );

    expect(parsed.legacyDetected).toBe(true);
    expect(parsed.selectedSalles).toEqual(["salle_ibis", "hall_amphitheatre"]);
    expect(parsed.formData.motifReservation).toBe("sport");
    expect(parsed.formData.dateReservation).toBe("2026-05-21");
    expect(parsed.formData.dateFinReservation).toBe("2026-05-21");
    expect(parsed.formData.heureDebut).toBe("09:45");
    expect(parsed.formData.heureFin).toBe("23:50");
  });

  it("builds detailed daily slots when the mode is enabled", () => {
    const parsed = parseReservationSallePayload(
      JSON.stringify({
        dateReservation: "2026-06-01",
        dateFinReservation: "2026-06-03",
        heureDebut: "09:00",
        heureFin: "17:00",
        useDetailedSchedule: true,
      })
    );

    expect(parsed.formData.useDetailedSchedule).toBe(true);
    expect(parsed.formData.horairesParJour).toEqual([
      { date: "2026-06-01", heureDebut: "09:00", heureFin: "17:00" },
      { date: "2026-06-02", heureDebut: "09:00", heureFin: "17:00" },
      { date: "2026-06-03", heureDebut: "09:00", heureFin: "17:00" },
    ]);
  });

  it("validates multi-day reservation requirements", () => {
    const error = validateReservationSalleFormInput(
      {
        motifReservation: "Atelier",
        dateReservation: "2026-06-05",
        dateFinReservation: "2026-06-04",
        heureDebut: "08:00",
        heureFin: "12:00",
        useDetailedSchedule: false,
        horairesParJour: [],
        nombreParticipants: "20",
        materielNecessaire: "",
        observations: "",
      },
      ["dojo"]
    );

    expect(error).toBe("La date de fin doit être postérieure ou égale à la date de début");
  });

  it("preserves existing fields while rebuilding payload", () => {
    const payload = buildReservationSallePayload({
      existingData: {
        cadreDSU: { responsableDSU: "DSU" },
      },
      association: {
        nomAssociation: "Association Test",
        adresse: "1 rue des Savanes",
        codePostal: "97310",
        ville: "Kourou",
      },
      selectedSalles: ["dojo"],
      formData: {
        motifReservation: "Atelier",
        dateReservation: "2026-06-01",
        dateFinReservation: "2026-06-02",
        heureDebut: "09:00",
        heureFin: "17:00",
        useDetailedSchedule: true,
        horairesParJour: [
          { date: "2026-06-01", heureDebut: "09:00", heureFin: "12:00" },
          { date: "2026-06-02", heureDebut: "14:00", heureFin: "18:00" },
        ],
        nombreParticipants: "25",
        materielNecessaire: "Chaises",
        observations: "RAS",
      },
    });

    expect(payload.cadreDSU).toEqual({ responsableDSU: "DSU" });
    expect(payload.sallesSelectionnees).toEqual(["DOJO"]);
    expect(payload.formulaireType).toBe("reservation_salle_mjs");
    expect(payload.horairesParJour).toHaveLength(2);
  });

  it("builds a readable reservation title", () => {
    expect(buildReservationSalleTitle(["dojo"], "2026-06-01")).toContain("DOJO");
  });

  it("computes the updated room pricing grid", () => {
    const bureauPricing = computeSallePricing({
      sallesIds: ["bureau_11_17"],
      usageType: "conventionne",
      frequency: "mensuel",
      dateReservation: "2026-06-01",
      dateFinReservation: "2026-06-01",
    });

    const ibisPricing = computeSallePricing({
      sallesIds: ["salle_ibis"],
      usageType: "conventionne",
      frequency: "demi_journee",
      dateReservation: "2026-06-01",
      dateFinReservation: "2026-06-01",
    });

    const unsupportedBureauHalfDay = computeSallePricing({
      sallesIds: ["bureau_11_17"],
      usageType: "conventionne",
      frequency: "demi_journee",
      dateReservation: "2026-06-01",
      dateFinReservation: "2026-06-01",
    });

    expect(bureauPricing.totalAmountCents).toBe(18819);
    expect(ibisPricing.totalAmountCents).toBe(8173);
    expect(unsupportedBureauHalfDay.unsupportedSalles).toEqual([
      { salleId: "bureau_11_17", salleNom: "Bureau 11–17 m²" },
    ]);
  });
});
