import json
from pathlib import Path
from typing import Optional

from pydantic import BaseModel

CONFIG_DIR = Path.home() / ".config" / "ha-cli"
CONFIG_FILE = CONFIG_DIR / "config.json"


class MqttConfig(BaseModel):
    """
    Configuration for the MQTT connection.

    Attributes:
        host (str): The hostname or IP address of the MQTT broker.
        port (int): The port number of the MQTT broker. Defaults to 1883.
        username (Optional[str]): The username for authentication. Defaults to None.
        password (Optional[str]): The password for authentication. Defaults to None.
        discovery_prefix (str): The prefix used for Home Assistant discovery topics. Defaults to "homeassistant".
    """

    host: str
    port: int = 1883
    username: Optional[str] = None
    password: Optional[str] = None
    discovery_prefix: str = "homeassistant"


class Config(BaseModel):
    """
    Global application configuration.

    Attributes:
        mqtt (MqttConfig): The MQTT connection configuration.
    """

    mqtt: MqttConfig


def load_config() -> Config:
    """
    Load the application configuration from the config file.

    If the configuration file does not exist, a default configuration is returned
    with 'localhost' as the MQTT host.

    Returns:
        Config: The loaded or default configuration.
    """
    if not CONFIG_FILE.exists():
        # Return default config if file doesn't exist
        return Config(mqtt=MqttConfig(host="localhost"))

    try:
        data = json.loads(CONFIG_FILE.read_text())
        return Config(**data)
    except Exception as e:
        # Fallback or error handling
        print(f"Error loading config: {e}")
        return Config(mqtt=MqttConfig(host="localhost"))


def save_config(config: Config) -> None:
    """
    Save the application configuration to the config file.

    Creates the configuration directory if it does not exist.

    Args:
        config (Config): The configuration object to save.
    """
    CONFIG_DIR.mkdir(parents=True, exist_ok=True)
    CONFIG_FILE.write_text(config.model_dump_json(indent=2))
