"""
Configuration management for Auror.

This module provides configuration classes and utilities for managing
application settings through environment variables and configuration files.
"""

import os
from dataclasses import dataclass
from pathlib import Path
from typing import Optional

from dotenv import load_dotenv


@dataclass
class AurorConfig:
    """
    Configuration for Auror messaging and authentication.

    Attributes:
        mqtt_host: MQTT broker hostname
        mqtt_port: MQTT broker port
        mqtt_topic: MQTT topic to subscribe to
        client_id: OAuth2 client ID for authentication
        client_secret: OAuth2 client secret for authentication
        audience: OAuth2 audience identifier
        auth0_token_url: Auth0 token endpoint URL
        pipeline_config: Path to the inference pipeline configuration file
        mock_mode: Enable mock inference mode (no actual video generation)
    """

    mqtt_host: str
    mqtt_port: int
    mqtt_topic: str
    client_id: str
    client_secret: str
    audience: str
    auth0_token_url: str = "https://roimarmier.eu.auth0.com/oauth/token"
    pipeline_config: str = "configs/ltxv-13b-0.9.8-distilled.yaml"
    mock_mode: bool = False

    @classmethod
    def from_env(cls, dotenv_path: Optional[str] = None) -> "AurorConfig":
        """
        Create configuration from environment variables.

        Automatically loads variables from .env file if present.

        Environment variables:
            AUROR_MQTT_HOST: MQTT broker hostname (required)
            AUROR_MQTT_PORT: MQTT broker port (default: 1883)
            AUROR_MQTT_TOPIC: MQTT topic (default: "video/ltx")
            AUROR_CLIENT_ID: OAuth2 client ID (required)
            AUROR_CLIENT_SECRET: OAuth2 client secret (required)
            AUROR_AUDIENCE: OAuth2 audience (required)
            AUROR_AUTH0_TOKEN_URL: Auth0 token URL (optional)
            AUROR_PIPELINE_CONFIG: Pipeline config path (optional)
            AUROR_MOCK_MODE: Enable mock inference mode (optional, default: false)

        Args:
            dotenv_path: Optional path to .env file. If None, searches for .env
                        in current directory and parent directories.

        Returns:
            AurorConfig instance

        Raises:
            ValueError: If required environment variables are missing
        """
        # Load environment variables from .env file
        load_dotenv(dotenv_path=dotenv_path)

        # Required variables
        required_vars = {
            "AUROR_MQTT_HOST": "mqtt_host",
            "AUROR_CLIENT_ID": "client_id",
            "AUROR_CLIENT_SECRET": "client_secret",
            "AUROR_AUDIENCE": "audience",
        }

        missing = [var for var in required_vars if not os.getenv(var)]
        if missing:
            raise ValueError(
                f"Missing required environment variables: {', '.join(missing)}"
            )

        # Build config
        config_dict = {
            "mqtt_host": os.getenv("AUROR_MQTT_HOST"),
            "mqtt_port": int(os.getenv("AUROR_MQTT_PORT", "1883")),
            "mqtt_topic": os.getenv("AUROR_MQTT_TOPIC", "video/ltx"),
            "client_id": os.getenv("AUROR_CLIENT_ID"),
            "client_secret": os.getenv("AUROR_CLIENT_SECRET"),
            "audience": os.getenv("AUROR_AUDIENCE"),
        }

        # Optional variables
        if auth0_url := os.getenv("AUROR_AUTH0_TOKEN_URL"):
            config_dict["auth0_token_url"] = auth0_url

        if pipeline_config := os.getenv("AUROR_PIPELINE_CONFIG"):
            config_dict["pipeline_config"] = pipeline_config

        # Mock mode (convert string to boolean)
        mock_mode_str = os.getenv("AUROR_MOCK_MODE", "false").lower()
        config_dict["mock_mode"] = mock_mode_str in ("true", "1", "yes")

        return cls(**config_dict)

    @classmethod
    def from_dict(cls, config_dict: dict) -> "AurorConfig":
        """
        Create configuration from a dictionary.

        Args:
            config_dict: Dictionary containing configuration parameters

        Returns:
            AurorConfig instance
        """
        return cls(**config_dict)

    def to_dict(self) -> dict:
        """
        Convert configuration to dictionary.

        Returns:
            Dictionary containing all configuration parameters
        """
        return {
            "mqtt_host": self.mqtt_host,
            "mqtt_port": self.mqtt_port,
            "mqtt_topic": self.mqtt_topic,
            "client_id": self.client_id,
            "client_secret": self.client_secret,
            "audience": self.audience,
            "auth0_token_url": self.auth0_token_url,
            "pipeline_config": self.pipeline_config,
            "mock_mode": self.mock_mode,
        }


def get_default_config() -> AurorConfig:
    """
    Get default configuration for development/testing.

    Returns:
        AurorConfig with default values

    Note:
        This should only be used for development. In production,
        use from_env() or from_dict() with actual credentials.
    """
    return AurorConfig(
        mqtt_host="videos.roimarmier.xyz",
        mqtt_port=1883,
        mqtt_topic="video/ltx",
        client_id="yraLXVcIKO7TGAHXf1imNu8zrGmbxEpW",
        client_secret="O0cpurbY4_xyz6nbcaDz6chMr_TuEVXi2VgeMaMNlmURjejui_ofaECHAw1vY2eH",
        audience="https://auror.roims.tech",
    )
