from __future__ import annotations

import json

from aegro.cli import app


class TestFuelSuppliesGet:
    def test_get_fuel_supply(self, runner, mock_settings, mock_client, temp_state):
        mock_client.get.return_value = {"_id": "fs-1", "assetKey": "a1"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["fuel-supplies", "get", "fs-1"])
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data["_id"] == "fs-1"
        mock_client.get.assert_called_once_with(
            "/pub/v1/assets/fuel-supplies/fs-1", api_key="key-1"
        )

    def test_get_fuel_supply_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, ["fuel-supplies", "get", "missing"])
        assert result.exit_code == 0
        assert "nao encontrad" in result.stdout.lower()

    def test_get_fuel_supply_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(app, ["fuel-supplies", "get", "fs-1"])
        assert result.exit_code != 0


class TestFuelSuppliesList:
    def test_list_no_filters(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = [{"_id": "fs-1"}]
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["fuel-supplies", "list"])
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert len(data) == 1
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["requiredPageNumber"] == 1
        assert call_body["maximumItemsPerPageCount"] == 50

    def test_list_with_asset_keys(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = []
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            ["fuel-supplies", "list", "--asset-key", "a1", "--asset-key", "a2"],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["assetKeys"] == ["a1", "a2"]

    def test_list_with_date_filters(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = []
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            ["fuel-supplies", "list", "--start-date", "2025-01-01", "--end-date", "2025-12-31"],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["startDate"] == "2025-01-01"
        assert call_body["endDate"] == "2025-12-31"

    def test_list_with_page(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = []
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(app, ["fuel-supplies", "list", "--page", "3"])
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["requiredPageNumber"] == 3

    def test_list_empty_result(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, ["fuel-supplies", "list"])
        assert result.exit_code == 0
        assert "nenhum" in result.stdout.lower()


class TestFuelSuppliesCreate:
    def test_create_required_fields(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = {"_id": "fs-new"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(
            app,
            [
                "fuel-supplies",
                "create",
                "--asset-key",
                "a1",
                "--date",
                "2025-06-01",
            ],
        )
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data["_id"] == "fs-new"
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["assetKey"] == "a1"
        assert call_body["occurrenceDate"] == "2025-06-01"
        assert "hourmeterAtOccurrence" not in call_body
        assert "observations" not in call_body
        assert "stockLocationKey" not in call_body
        assert mock_client.post.call_args.args[0] == "/pub/v1/assets/fuel-supplies"

    def test_create_all_fields(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = {"_id": "fs-new"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            [
                "fuel-supplies",
                "create",
                "--asset-key",
                "a1",
                "--date",
                "2025-06-01",
                "--hourmeter",
                "1500.5",
                "--observations",
                "Diesel S10",
                "--stock-location-key",
                "loc1",
            ],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["assetKey"] == "a1"
        assert call_body["occurrenceDate"] == "2025-06-01"
        assert call_body["hourmeterAtOccurrence"] == 1500.5
        assert call_body["observations"] == "Diesel S10"
        assert call_body["stockLocationKey"] == "loc1"

    def test_create_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(
            app,
            [
                "fuel-supplies",
                "create",
                "--asset-key",
                "a1",
                "--date",
                "2025-06-01",
            ],
        )
        assert result.exit_code != 0


class TestFuelSuppliesUpdate:
    def test_update(self, runner, mock_settings, mock_client, temp_state):
        mock_client.put.return_value = {"_id": "fs-1"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(
            app,
            [
                "fuel-supplies",
                "update",
                "fs-1",
                "--date",
                "2025-06-02",
                "--hourmeter",
                "1600",
            ],
        )
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data["_id"] == "fs-1"
        call_body = mock_client.put.call_args.kwargs["json_body"]
        assert call_body["occurrenceDate"] == "2025-06-02"
        assert call_body["hourmeterAtOccurrence"] == 1600.0
        assert mock_client.put.call_args.args[0] == "/pub/v1/assets/fuel-supplies/fs-1"

    def test_update_all_fields(self, runner, mock_settings, mock_client, temp_state):
        mock_client.put.return_value = {"_id": "fs-1"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            [
                "fuel-supplies",
                "update",
                "fs-1",
                "--asset-key",
                "a2",
                "--date",
                "2025-06-02",
                "--hourmeter",
                "1600",
                "--observations",
                "Correcao",
                "--stock-location-key",
                "loc2",
            ],
        )
        call_body = mock_client.put.call_args.kwargs["json_body"]
        assert call_body["assetKey"] == "a2"
        assert call_body["occurrenceDate"] == "2025-06-02"
        assert call_body["hourmeterAtOccurrence"] == 1600.0
        assert call_body["observations"] == "Correcao"
        assert call_body["stockLocationKey"] == "loc2"

    def test_update_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(
            app,
            ["fuel-supplies", "update", "fs-1", "--date", "2025-06-02"],
        )
        assert result.exit_code != 0
