"""
Beispiel für ein Inventory mit allen möglichen Datentypen.

Zeigt die Verwendung der High-Level API zum Erstellen eines Inventars
mit Properties für jeden verfügbaren DataType.
"""

from __future__ import annotations

from datetime import datetime

from questra_authentication import QuestraAuthentication

from questra_data import (
    BoolProperty,
    DateProperty,
    DateTimeOffsetProperty,
    DateTimeProperty,
    DecimalProperty,
    FileProperty,
    GuidProperty,
    IntProperty,
    LongProperty,
    QuestraData,
    StringProperty,
    TimeProperty,
    TimeSeriesProperty,
    TimeUnit,
    ValueAlignment,
    ValueAvailability,
)


def main():
    """Erstellt ein Inventory mit allen möglichen Datentypen."""

    # ===== Client initialisieren =====
    print("=" * 60)
    print("Inventory mit allen Datentypen erstellen")
    print("=" * 60)
    print()

    auth_client = QuestraAuthentication(
        url="https://authentik.dev.questra.s2o.dev",
        interactive=True,
    )

    client = QuestraData(
        graphql_url="https://dev.questra.s2o.dev/dynamic-objects/graphql",
        auth_client=auth_client,
    )

    print(f"Client initialisiert: {client.is_authenticated()}")
    print()

    # ===== Namespace erstellen =====
    ns_result = client.create_namespace(
        name="AllTypesDemo", description="Namespace für Datentyp-Demo"
    )
    print(f"Namespace: {ns_result.name} (existierte: {ns_result.existed})")
    print()

    # ===== Properties für alle Datentypen definieren =====
    properties = [
        # STRING: Text mit maximaler Länge
        StringProperty(
            propertyName="text_field",
            maxLength=200,
            isCaseSensitive=False,
            isRequired=False,
            description="Text-Feld mit max. 200 Zeichen",
        ),
        # INT: Ganzzahl 32-bit (-2.147.483.648 bis 2.147.483.647)
        IntProperty(
            propertyName="int_field", isRequired=False, description="Integer 32-bit"
        ),
        # LONG: Ganzzahl 64-bit (-9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807)
        LongProperty(
            propertyName="long_field",
            isRequired=False,
            description="Long Integer 64-bit",
        ),
        # DECIMAL: Dezimalzahl mit 16 Vorkommastellen, 8 Nachkommastellen
        DecimalProperty(
            propertyName="decimal_field",
            isRequired=False,
            description="Dezimalzahl (16.8 Precision)",
        ),
        # BOOLEAN: Wahrheitswert (true/false)
        BoolProperty(
            propertyName="boolean_field",
            isRequired=False,
            description="Boolean true/false",
        ),
        # DATE_TIME: Datum und Uhrzeit (ISO-8601 mit Mikrosekunden)
        DateTimeProperty(
            propertyName="datetime_field",
            isRequired=False,
            description="DateTime mit Mikrosekunden",
        ),
        # DATE_TIME_OFFSET: Datum und Uhrzeit mit Zeitzone
        DateTimeOffsetProperty(
            propertyName="datetimeoffset_field",
            isRequired=False,
            description="DateTime mit Zeitzone",
        ),
        # DATE: Nur Datum (ISO-8601: YYYY-MM-DD)
        DateProperty(
            propertyName="date_field",
            isRequired=False,
            description="Nur Datum (YYYY-MM-DD)",
        ),
        # TIME: Nur Uhrzeit (HH:mm:ss.ffffff)
        TimeProperty(
            propertyName="time_field",
            isRequired=False,
            description="Nur Uhrzeit mit Mikrosekunden",
        ),
        # GUID: Global Unique Identifier (UUID)
        GuidProperty(
            propertyName="guid_field", isRequired=False, description="UUID / GUID"
        ),
        # FILE: Datei mit maximaler Größe
        FileProperty(
            propertyName="file_field",
            maxLength=10485760,  # 10 MB in Bytes
            isRequired=False,
            description="Datei mit max. 10 MB",
        ),
        # TIME_SERIES: Zeitreihe mit Intervall und Einheit
        TimeSeriesProperty(
            propertyName="timeseries_field",
            timeUnit=TimeUnit.MINUTE,
            multiplier=15,
            unit="kWh",
            valueAlignment=ValueAlignment.LEFT,
            valueAvailability=ValueAvailability.AT_INTERVAL_BEGIN,
            timeZone="Europe/Berlin",
            isRequired=False,
            description="Zeitreihe im 15-Minuten-Intervall",
        ),
        # Zusätzlich: Array-Felder (isArray=True)
        StringProperty(
            propertyName="string_array",
            maxLength=100,
            isRequired=False,
            isArray=True,
            description="Array von Strings",
        ),
        IntProperty(
            propertyName="int_array",
            isRequired=False,
            isArray=True,
            description="Array von Integers",
        ),
        # Unique und Required Beispiel
        StringProperty(
            propertyName="unique_identifier",
            maxLength=50,
            isRequired=True,
            isUnique=True,
            description="Eindeutige ID (pflicht)",
        ),
    ]

    # ===== Inventory erstellen =====
    inv_result = client.create_inventory(
        name="AllDataTypes",
        namespace_name="AllTypesDemo",
        properties=properties,
        description="Inventory mit allen verfügbaren Datentypen",
    )

    print(f"Inventory: {inv_result.name} (existierte: {inv_result.existed})")
    print()

    # ===== Übersicht ausgeben =====
    print("=" * 60)
    print("Erstellte Properties:")
    print("=" * 60)
    for prop in properties:
        array_marker = " (Array)" if prop.isArray else ""
        required_marker = " [Required]" if prop.isRequired else ""
        unique_marker = " [Unique]" if prop.isUnique else ""
        prop_type = type(prop).__name__
        print(
            f"  {prop.propertyName:25} -> {prop_type:20}{array_marker}{required_marker}{unique_marker}"
        )
    print()

    # ===== Beispiel-Item erstellen =====
    print("=" * 60)
    print("Beispiel-Item erstellen")
    print("=" * 60)

    example_item = {
        "unique_identifier": "DEMO-001",
        "text_field": "Beispieltext",
        "int_field": 42,
        "long_field": 9223372036854775807,
        "decimal_field": "123.456",
        "boolean_field": True,
        "datetime_field": datetime.now().isoformat(),
        "date_field": "2025-01-15",
        "time_field": "14:30:00.123456",
        "guid_field": "550e8400-e29b-41d4-a716-446655440000",
        "string_array": ["Wert1", "Wert2", "Wert3"],
        "int_array": [1, 2, 3, 4, 5],
        "timeseries_field": None,  # Zeitreihe wird automatisch angelegt
    }

    created_items = client.create_items(
        inventory_name="AllDataTypes",
        namespace_name="AllTypesDemo",
        items=[example_item],
    )

    print(f"Item erstellt: ID = {created_items[0]['_id']}")
    print()

    # ===== Item wieder auslesen =====
    loaded_items = client.list_items(
        inventory_name="AllDataTypes",
        namespace_name="AllTypesDemo",
        properties=[
            "_id",
            "unique_identifier",
            "text_field",
            "int_field",
            "long_field",
            "decimal_field",
            "boolean_field",
            "date_field",
            "string_array",
        ],
        limit=1,
    )

    if loaded_items:
        print("=" * 60)
        print("Geladenes Item:")
        print("=" * 60)
        for key, value in loaded_items[0].items():
            print(f"  {key:25} = {value}")
        print()

    print("=" * 60)
    print("Fertig!")
    print("=" * 60)


if __name__ == "__main__":
    main()
