from __future__ import annotations

import json

from aegro.cli import app


class TestHarvestLogsGet:
    def test_get_harvest_log(self, runner, mock_settings, mock_client, temp_state):
        mock_client.get.return_value = {"_id": "hl-1", "cropKey": "c1"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["harvest-logs", "get", "hl-1"])
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data["_id"] == "hl-1"
        mock_client.get.assert_called_once_with("/pub/v1/harvest-logs/hl-1", api_key="key-1")

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

    def test_get_harvest_log_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(app, ["harvest-logs", "get", "hl-1"])
        assert result.exit_code != 0


class TestHarvestLogsCreate:
    def test_create_required_fields(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = {"_id": "hl-new"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(
            app,
            [
                "harvest-logs",
                "create",
                "--crop-key",
                "c1",
                "--date",
                "2025-06-01",
            ],
        )
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data["_id"] == "hl-new"
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["cropKey"] == "c1"
        assert call_body["date"] == "2025-06-01"
        assert call_body["calculationMode"] == "AUTOMATIC"
        assert "cropGlebes" not in call_body
        assert "seedKey" not in call_body
        assert "destinationKey" not in call_body
        assert "grossWeight" not in call_body
        assert mock_client.post.call_args.args[0] == "/pub/v1/harvest-logs"

    def test_create_with_glebes(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = {"_id": "hl-new"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            [
                "harvest-logs",
                "create",
                "--crop-key",
                "c1",
                "--date",
                "2025-06-01",
                "--crop-glebe",
                "g1",
                "--crop-glebe",
                "g2",
            ],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["cropGlebes"] == [
            {"cropGlebeKey": "g1"},
            {"cropGlebeKey": "g2"},
        ]

    def test_create_with_weights(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = {"_id": "hl-new"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            [
                "harvest-logs",
                "create",
                "--crop-key",
                "c1",
                "--date",
                "2025-06-01",
                "--gross-weight",
                "1000",
                "--tare-weight",
                "200",
                "--net-weight",
                "800",
                "--discounted-weight",
                "50",
                "--product-weight",
                "750",
            ],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["grossWeight"] == {"magnitude": 1000.0, "unit": "kg"}
        assert call_body["tareWeight"] == {"magnitude": 200.0, "unit": "kg"}
        assert call_body["netWeight"] == {"magnitude": 800.0, "unit": "kg"}
        assert call_body["discountedWeight"] == {"magnitude": 50.0, "unit": "kg"}
        assert call_body["productWeight"] == {"magnitude": 750.0, "unit": "kg"}

    def test_create_all_fields(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = {"_id": "hl-new"}
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            [
                "harvest-logs",
                "create",
                "--crop-key",
                "c1",
                "--date",
                "2025-06-01",
                "--crop-glebe",
                "g1",
                "--calculation-mode",
                "MANUAL",
                "--seed-key",
                "seed-1",
                "--destination-key",
                "dest-1",
                "--gross-weight",
                "1000",
                "--observations",
                "Colheita parcial",
                "--identifier",
                "ID-001",
                "--invoice-code",
                "NF-123",
                "--romaneio-code",
                "ROM-456",
            ],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["cropKey"] == "c1"
        assert call_body["date"] == "2025-06-01"
        assert call_body["calculationMode"] == "MANUAL"
        assert call_body["cropGlebes"] == [{"cropGlebeKey": "g1"}]
        assert call_body["seedKey"] == "seed-1"
        assert call_body["destinationKey"] == "dest-1"
        assert call_body["grossWeight"] == {"magnitude": 1000.0, "unit": "kg"}
        assert call_body["observations"] == "Colheita parcial"
        assert call_body["identifier"] == "ID-001"
        assert call_body["invoiceCode"] == "NF-123"
        assert call_body["romaneioCode"] == "ROM-456"

    def test_create_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(
            app,
            [
                "harvest-logs",
                "create",
                "--crop-key",
                "c1",
                "--date",
                "2025-06-01",
            ],
        )
        assert result.exit_code != 0
