from pathlib import Path
from typing import Generator

import pytest

from hamqtt.config import Config, MqttConfig, load_config, save_config


@pytest.fixture  # type: ignore[misc]
def mock_config_path(tmp_path: Path) -> Generator[Path, None, None]:
    config_dir = tmp_path / ".config" / "ha-cli"
    config_file = config_dir / "config.json"

    # Patch the constants in the config module
    with pytest.MonkeyPatch.context() as m:
        m.setattr("hamqtt.config.CONFIG_DIR", config_dir)
        m.setattr("hamqtt.config.CONFIG_FILE", config_file)
        yield config_file


def test_load_config_defaults(mock_config_path: Path) -> None:
    """Test loading config when file doesn't exist returns defaults"""
    config = load_config()
    assert config.mqtt.host == "localhost"
    assert config.mqtt.port == 1883
    assert config.mqtt.username is None
    assert config.mqtt.password is None


def test_save_and_load_config(mock_config_path: Path) -> None:
    """Test saving and then loading a configuration"""
    mqtt_config = MqttConfig(host="192.168.1.100", port=1884, username="user", password="password")
    config = Config(mqtt=mqtt_config)

    save_config(config)

    assert mock_config_path.exists()

    loaded_config = load_config()
    assert loaded_config.mqtt.host == "192.168.1.100"
    assert loaded_config.mqtt.port == 1884
    assert loaded_config.mqtt.username == "user"
    assert loaded_config.mqtt.password == "password"


def test_load_config_invalid_json(mock_config_path: Path) -> None:
    """Test loading config with invalid JSON returns defaults"""
    mock_config_path.parent.mkdir(parents=True, exist_ok=True)
    mock_config_path.write_text("{invalid_json")

    config = load_config()
    # Should fallback to default
    assert config.mqtt.host == "localhost"
