"""Gemeinsam genutzte TimeSeries-Modelle für GraphQL und REST API."""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from enum import Enum


class TimeUnit(str, Enum):
    """
    Zeiteinheiten für Intervalle.

    Attributes:
        SECOND: Sekunde
        MINUTE: Minute
        HOUR: Stunde
        DAY: Tag
        WEEK: Woche
        MONTH: Monat
        QUARTER: Quartal
        YEAR: Jahr
    """

    SECOND = "SECOND"
    MINUTE = "MINUTE"
    HOUR = "HOUR"
    DAY = "DAY"
    WEEK = "WEEK"
    MONTH = "MONTH"
    QUARTER = "QUARTER"
    YEAR = "YEAR"


class Aggregation(str, Enum):
    """
    Aggregationsarten für Zeitreihen.

    Attributes:
        SUM: Summe aller Werte
        AVERAGE: Durchschnitt aller Werte
        MIN: Kleinster Wert
        MAX: Größter Wert
        MOST_FREQUENTLY: Häufigster Wert
        ABS_MIN: Betragsmäßig kleinster Wert
        ABS_MAX: Betragsmäßig größter Wert
        FIRST_VALUE: Erster Wert im Intervall
        LAST_VALUE: Letzter Wert im Intervall
    """

    SUM = "SUM"
    AVERAGE = "AVERAGE"
    MIN = "MIN"
    MAX = "MAX"
    MOST_FREQUENTLY = "MOST_FREQUENTLY"
    ABS_MIN = "ABS_MIN"
    ABS_MAX = "ABS_MAX"
    FIRST_VALUE = "FIRST_VALUE"
    LAST_VALUE = "LAST_VALUE"


class Quality(str, Enum):
    """
    Qualitätswerte für Zeitreihen-Datenpunkte.

    Attributes:
        NO_VALUE: Kein Wert vorhanden
        MANUALLY_REPLACED: Manuell ersetzt
        FAULTY: Fehlerhaft
        VALID: Gültig/Valide
        SCHEDULE: Geplant/Schedule
        MISSING: Fehlend
        ACCOUNTED: Verrechnet
        ESTIMATED: Geschätzt
        INTERPOLATED: Interpoliert
    """

    NO_VALUE = "NO_VALUE"
    MANUALLY_REPLACED = "MANUALLY_REPLACED"
    FAULTY = "FAULTY"
    VALID = "VALID"
    SCHEDULE = "SCHEDULE"
    MISSING = "MISSING"
    ACCOUNTED = "ACCOUNTED"
    ESTIMATED = "ESTIMATED"
    INTERPOLATED = "INTERPOLATED"


class QuotationBehavior(str, Enum):
    """
    Quotierungs-Verhalten für Zeitreihen.

    Attributes:
        LATEST_EXACTLY_AT: Genau zum Zeitpunkt
        LATEST: Letzter Wert vor oder am Zeitpunkt
        LATEST_NO_FUTURE: Letzter Wert vor oder am Zeitpunkt, keine zukünftigen Werte
    """

    LATEST_EXACTLY_AT = "LATEST_EXACTLY_AT"
    LATEST = "LATEST"
    LATEST_NO_FUTURE = "LATEST_NO_FUTURE"


class ValueAlignment(str, Enum):
    """
    Wert-Ausrichtung für Zeitreihen.

    Attributes:
        LEFT: Linksbündig (Wert gilt ab Zeitpunkt)
        RIGHT: Rechtsbündig (Wert gilt bis Zeitpunkt)
        NONE: Keine Ausrichtung
    """

    LEFT = "LEFT"
    RIGHT = "RIGHT"
    NONE = "NONE"


class ValueAvailability(str, Enum):
    """
    Wert-Verfügbarkeit für Zeitreihen.

    Attributes:
        AT_INTERVAL_BEGIN: Wert verfügbar am Intervall-Anfang
        AT_INTERVAL_END: Wert verfügbar am Intervall-Ende
    """

    AT_INTERVAL_BEGIN = "AT_INTERVAL_BEGIN"
    AT_INTERVAL_END = "AT_INTERVAL_END"


@dataclass
class Interval:
    """Intervall-Definition für Zeitreihen."""

    time_unit: TimeUnit
    multiplier: int = 1


@dataclass
class TimeSeriesValue:
    """Einzelner Datenpunkt einer Zeitreihe."""

    time: datetime
    value: float
    quality: Quality | None = None
