"""
EN: Centralized custom exception and error message management for the BBW University Research Platform backend.
    - Defines language-aware exceptions for robust error handling.
DE: Zentrale Verwaltung von benutzerdefinierten Ausnahmen und Fehlermeldungen für das Backend der Forschungsplattform der bbw Hochschule.
    - Definiert sprachsensitive Ausnahmen für robuste Fehlerbehandlung.
"""


# --- Language Enum ---
from enum import Enum, auto

class Sprache(Enum):
    """
    DE: Definiert die unterstützten Sprachen für Fehlermeldungen, um Typsicherheit zu gewährleisten.
    EN: Defines the supported languages for error messages, ensuring type safety.
    """
    DE = auto()
    EN = auto()

# --- Base Exception ---

class Anwendungsfehler(Exception):
    """
    DE: Basisklasse für alle anwendungsspezifischen Fehler.
        Jeder Fehler enthält eine deutsche und eine englische Nachricht.
    EN: Base class for all application-specific errors.
        Each error contains a German and an English message.
    """

    def __init__(self, nachricht_de: str, nachricht_en: str):
        # DE: Speichert die Fehlermeldungen für jede Sprache als separate Attribute.
        # EN: Stores the error messages for each language as separate attributes.
        self.nachricht_de = nachricht_de
        self.nachricht_en = nachricht_en

        # DE: Ruft den Konstruktor der Basisklasse `Exception` mit einer kombinierten Nachricht auf.
        # EN: Calls the base class `Exception` constructor with a combined message.
        super().__init__(f"{self.nachricht_de} / {self.nachricht_en}")

    def get_nachricht(self, sprache: Sprache) -> str:
        """
        DE: Gibt die Fehlermeldung in der gewählten Sprache zurück.
            Verwendet eine Zuordnung (Mapping), um den Code sauber und erweiterbar zu halten.
        EN: Returns the error message in the selected language.
            Uses a mapping to keep the code clean and extensible.
        """
        # DE: Eine Zuordnung von Sprache zu Nachrichtenattribut.
        # EN: A mapping from language to message attribute.
        nachrichten_map = {
            Sprache.DE: self.nachricht_de,
            Sprache.EN: self.nachricht_en,
        }
        # DE: Gibt die Nachricht für die angegebene Sprache zurück oder die Standard-String-Darstellung als Fallback.
        # EN: Returns the message for the specified language or the default string representation as a fallback.
        return nachrichten_map.get(sprache, str(self))

# --- Specific Custom Exceptions (Standardized) ---
# DE: Jede der folgenden Klassen erbt von `Anwendungsfehler` und konstruiert ihre Nachrichten intern.
# EN: Each of the following classes inherits from `Anwendungsfehler` and constructs its messages internally.

class AllgemeinerFehler(Anwendungsfehler):
    """DE: Für allgemeine, nicht spezifizierte Laufzeitfehler. / EN: For general, unspecified runtime errors."""
    def __init__(self, details: str):
        super().__init__(
            nachricht_de=f"Ein unerwarteter Fehler ist aufgetreten: {details}",
            nachricht_en=f"An unexpected error has occurred: {details}"
        )

class KeinBestandError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn ein Material nicht auf Lager ist. / EN: Raised when a material is out of stock."""
    def __init__(self, material_name: str):
        super().__init__(
            nachricht_de=f"Das Material '{material_name}' ist nicht auf Lager.",
            nachricht_en=f"The material '{material_name}' is out of stock."
        )

class ObjektPasstNichtError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn das Teil nicht in den Drucker passt. / EN: Raised if the part does not fit in the printer."""
    def __init__(self, teil_name: str, drucker_name: str):
        super().__init__(
            nachricht_de=f"Das Teil '{teil_name}' passt nicht in den Bauraum des Druckers '{drucker_name}'.",
            nachricht_en=f"The part '{teil_name}' does not fit in the build volume of the printer '{drucker_name}'."
        )

class UnzureichendesMaterialError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn nicht genug Material für ein Teil vorhanden ist. / EN: Raised if there is not enough material."""
    def __init__(self, teil_name: str, material_name: str):
        super().__init__(
            nachricht_de=f"Nicht genügend Material '{material_name}' vorhanden, um das Teil '{teil_name}' zu drucken.",
            nachricht_en=f"Not enough material '{material_name}' available to print the part '{teil_name}'."
        )

class DateiNichtGefundenError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn eine benötigte Datendatei fehlt. / EN: Raised if a required data file is missing."""
    def __init__(self, dateiname: str):
        super().__init__(
            nachricht_de=f"Die Datendatei '{dateiname}' konnte nicht gefunden werden.",
            nachricht_en=f"The data file '{dateiname}' could not be found."
        )

class UngueltigesDateiformatError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn eine Datei ein unerwartetes Format hat. / EN: Raised if a file has an unexpected format."""
    def __init__(self, dateiname: str, details: str):
        super().__init__(
            nachricht_de=f"Die Datei '{dateiname}' hat ein ungültiges Format. Grund: {details}",
            nachricht_en=f"The file '{dateiname}' has an invalid format. Reason: {details}"
        )

class UngueltigeAuswahlError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn eine unmögliche Option gewählt wird. / EN: Raised if an impossible option is chosen."""
    def __init__(self, meldung: str):
        super().__init__(
            nachricht_de=f"Ungültige Auswahl: {meldung}",
            nachricht_en=f"Invalid selection: {meldung}"
        )

class DateierstellungFehlgeschlagenError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn die Erstellung einer Ausgabedatei fehlschlägt. / EN: Raised if creating an output file fails."""
    def __init__(self, dateiname: str):
        super().__init__(
            nachricht_de=f"Die Erstellung der Datei '{dateiname}' ist fehlgeschlagen.",
            nachricht_en=f"Failed to create the file '{dateiname}'."
        )

class UnvollstaendigeAuswahlError(Anwendungsfehler):
    """DE: Wird ausgelöst, wenn nicht alle nötigen Optionen ausgewählt wurden. / EN: Raised if not all necessary options have been selected."""
    def __init__(self):
        super().__init__(
            nachricht_de="Bitte wählen Sie alle erforderlichen Optionen aus (Teil, Material, Qualität, Drucker).",
            nachricht_en="Please select all required options (Part, Material, Quality, Printer)."
        )

class BerechnungsFehler(Anwendungsfehler):
    """DE: Fehler, die während der Berechnung auftreten. / EN: Errors that occur during calculation."""
    def __init__(self, details: str):
        # DE: Konstruiert Nachrichten basierend auf den Fehlerdetails.
        # EN: Constructs messages based on the error details.
        super().__init__(
            nachricht_de=f"Berechnungsfehler: {details}",
            nachricht_en=f"Calculation error: {details}"
        )
"""
class CSVVerarbeitungsFehler(Anwendungsfehler):
    ""DE: Fehler bei der Verarbeitung von CSV-Dateien. / EN: Error processing CSV files.""
    def __init__(self, details: str):
        super().__init__(
            nachricht_de=f"CSV-Verarbeitungsfehler: {details}",
            nachricht_en=f"CSV processing error: {details}"
        )
"""
class ValidierungsFehler(Exception):
    """
    DE: Eine benutzerdefinierte Ausnahme für Validierungsfehler mit mehrsprachiger Unterstützung.
    EN: A custom exception for validation errors with multilingual support.
    """
    def __init__(self, msg_de: str, msg_es: str = None, msg_en: str = None):
        """
        DE: Initialisiert die Ausnahme mit Nachrichten in verschiedenen Sprachen.
        EN: Initializes the exception with messages in different languages.
        """
        super().__init__(msg_de)
        self.msg_de = msg_de
        self.msg_en = msg_en if msg_en is not None else msg_de

    def get_message_for_lang(self, lang: str) -> str:
        """
        DE: Gibt die Fehlermeldung in der angegebenen Sprache zurück.
        EN: Returns the error message in the specified language.
        """
        if lang == 'en':
            return self.msg_en
        return self.msg_de

class CSVVerarbeitungsFehler(Exception):
    """
    DE: Eine benutzerdefinierte Ausnahme für Fehler beim Verarbeiten von CSV-Dateien.
    EN: A custom exception for errors when processing CSV files.
    """
    def __init__(self, msg_de: str, msg_en: str = None):
        super().__init__(msg_de)
        self.msg_de = msg_de
        self.msg_en = msg_en if msg_en is not None else msg_de

    def get_message_for_lang(self, lang: str) -> str:
        if lang == 'en':
            return self.msg_en
        return self.msg_de