package de.assecutor.votianlt.model.invoices;

import lombok.Data;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.CompoundIndexes;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

import java.time.Instant;

/**
 * Audit-Eintrag für jede aus dem Rechnungsnummern-Counter gezogene Nummer.
 * Erlaubt nachzuweisen, dass jede Lücke im fortlaufenden Nummernkreis erklärt
 * werden kann (vergeben aber nicht ausgestellt → entweder offen oder begründet
 * verworfen). Pflichtgrundlage: § 14 Abs. 4 Nr. 4 UStG i.V.m. GoBD.
 *
 * Pro (userId, sequence) existiert genau eine Reservierung — ein Eindeutigkeits-
 * Index erzwingt das auch bei nebenläufigen Aufrufen.
 */
@Data
@Document(collection = "invoice_number_reservations")
@CompoundIndexes({
        @CompoundIndex(name = "user_sequence_unique", def = "{'userId': 1, 'sequence': 1}", unique = true),
        @CompoundIndex(name = "user_status", def = "{'userId': 1, 'status': 1}")
})
public class InvoiceNumberReservation {

    @Id
    private ObjectId id;

    @Indexed
    private ObjectId userId;

    /** Vollständige formatierte Rechnungsnummer wie sie auf dem Beleg erscheint (Präfix + Sequenz). */
    private String number;

    /** Roh-Sequenznummer aus dem Counter — Basis für Lücken-Analyse. */
    private long sequence;

    /** Präfix, mit dem die Nummer formatiert wurde — relevant, falls der Anwender den Präfix später ändert. */
    private String prefix;

    private Instant reservedAt;

    /** Anzeigename des reservierenden Nutzers (z.B. „Anna Müller") oder „system" für Hintergrundprozesse. */
    private String reservedBy;

    private InvoiceNumberReservationStatus status;

    /** Bei status=USED: ID der ausgestellten Rechnung. */
    private String invoiceId;

    private Instant usedAt;

    /** Bei status=VOIDED: vom Anwender erfasster Grund — Pflichtfeld für betriebsprüfungstaugliche Erklärung. */
    private String voidReason;

    private Instant voidedAt;
}
