from __future__ import annotations

import json

from aegro.cli import app


class TestWeatherGet:
    def test_get_weather_log(self, runner, mock_settings, mock_client, temp_state):
        mock_client.get.return_value = {"_id": "w1", "date": "2025-06-01"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["weather", "get", "w1"])
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data["date"] == "2025-06-01"
        mock_client.get.assert_called_once_with("/pub/v1/weather-logs/w1", api_key="key-1")

    def test_get_weather_log_not_found(self, runner, mock_settings, mock_client, temp_state):
        mock_client.get.return_value = None
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["weather", "get", "missing"])
        assert result.exit_code == 0
        assert "nao encontrad" in result.stdout.lower()

    def test_get_weather_log_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(app, ["weather", "get", "w1"])
        assert result.exit_code != 0


class TestWeatherCreate:
    def test_create_weather_log(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = {"_id": "w-new", "date": "2025-06-01"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(
            app,
            [
                "weather",
                "create",
                "--weather-station-key",
                "ws1",
                "--date",
                "2025-06-01",
                "--precipitation",
                "12.5",
                "--precipitation-unit",
                "mm",
                "--temperature",
                "28.0",
                "--temperature-unit",
                "CELSIUS",
                "--humidity",
                "65.0",
                "--pressure",
                "1013.25",
            ],
        )
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data["_id"] == "w-new"
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["weatherStationKey"] == "ws1"
        assert call_body["date"] == "2025-06-01"
        assert call_body["precipitation"]["magnitude"] == 12.5
        assert call_body["precipitation"]["unit"] == "mm"
        assert call_body["temperature"]["magnitude"] == 28.0
        assert call_body["temperature"]["unit"] == "CELSIUS"
        assert call_body["relativeHumidity"] == 65.0
        assert call_body["atmosphericPressureInHpa"] == 1013.25

    def test_create_weather_log_minimal(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = None
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(
            app,
            [
                "weather",
                "create",
                "--weather-station-key",
                "ws1",
                "--date",
                "2025-06-01",
            ],
        )
        assert result.exit_code == 0
        assert "criado" in result.stdout.lower()
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["weatherStationKey"] == "ws1"
        assert call_body["date"] == "2025-06-01"
        assert "precipitation" not in call_body
        assert "temperature" not in call_body
        assert "relativeHumidity" not in call_body
        assert "atmosphericPressureInHpa" not in call_body

    def test_create_weather_log_precipitation_only(
        self, runner, mock_settings, mock_client, temp_state
    ):
        mock_client.post.return_value = None
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            [
                "weather",
                "create",
                "--weather-station-key",
                "ws1",
                "--date",
                "2025-06-01",
                "--precipitation",
                "10.0",
                "--precipitation-unit",
                "mm",
            ],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["precipitation"]["magnitude"] == 10.0
        assert call_body["precipitation"]["unit"] == "mm"
        assert "temperature" not in call_body

    def test_create_weather_log_precipitation_without_unit_errors(
        self, runner, mock_settings, mock_client, temp_state
    ):
        """Precipitation without unit should produce a validation error."""
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(
            app,
            [
                "weather",
                "create",
                "--weather-station-key",
                "ws1",
                "--date",
                "2025-06-01",
                "--precipitation",
                "10.0",
            ],
        )
        assert result.exit_code != 0
        mock_client.post.assert_not_called()

    def test_create_weather_log_temperature_without_unit_errors(
        self, runner, mock_settings, mock_client, temp_state
    ):
        """Temperature without unit should produce a validation error."""
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(
            app,
            [
                "weather",
                "create",
                "--weather-station-key",
                "ws1",
                "--date",
                "2025-06-01",
                "--temperature",
                "28.0",
            ],
        )
        assert result.exit_code != 0
        mock_client.post.assert_not_called()

    def test_create_weather_log_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(
            app,
            [
                "weather",
                "create",
                "--weather-station-key",
                "ws1",
                "--date",
                "2025-06-01",
            ],
        )
        assert result.exit_code != 0
