from __future__ import annotations

import json

from aegro.cli import app


class TestCatalogsList:
    def test_list_catalogs(self, runner, mock_settings, mock_client, temp_state):
        mock_client.get.return_value = [{"_id": "cat-1", "name": "Insumos"}]
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["catalogs", "list"])
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert len(data) == 1
        assert data[0]["name"] == "Insumos"
        mock_client.get.assert_called_once_with("/pub/v1/catalogs", api_key="key-1")

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

    def test_list_catalogs_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(app, ["catalogs", "list"])
        assert result.exit_code != 0


class TestCatalogsElementKeys:
    def test_element_keys(self, runner, mock_settings, mock_client, temp_state):
        mock_client.get.return_value = ["key-a", "key-b", "key-c"]
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["catalogs", "element-keys", "cat-1"])
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert data == ["key-a", "key-b", "key-c"]
        mock_client.get.assert_called_once_with(
            "/pub/v1/catalogs/cat-1/elements/keys", api_key="key-1"
        )

    def test_element_keys_empty(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, ["catalogs", "element-keys", "cat-1"])
        assert result.exit_code == 0
        assert "nenhum" in result.stdout.lower()

    def test_element_keys_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(app, ["catalogs", "element-keys", "cat-1"])
        assert result.exit_code != 0


class TestCatalogsElements:
    def test_elements_no_filters(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = [{"_id": "el-1", "name": "Ureia"}]
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        result = runner.invoke(app, ["catalogs", "elements", "cat-1"])
        assert result.exit_code == 0
        data = json.loads(result.stdout)
        assert len(data) == 1
        assert mock_client.post.call_args.args[0] == "/pub/v1/catalogs/cat-1/elements/filter"
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["requiredPageNumber"] == 1
        assert call_body["maximumItemsPerPageCount"] == 50

    def test_elements_with_filters(self, runner, mock_settings, mock_client, temp_state):
        mock_client.post.return_value = []
        runner.invoke(app, ["farms", "select", "Fazenda Sul"])
        runner.invoke(
            app,
            [
                "catalogs",
                "elements",
                "cat-1",
                "--category",
                "SEED",
                "--category",
                "FERTILIZER",
                "--search-text",
                "Ureia",
                "--page",
                "2",
            ],
        )
        call_body = mock_client.post.call_args.kwargs["json_body"]
        assert call_body["categories"] == ["SEED", "FERTILIZER"]
        assert call_body["searchText"] == "Ureia"
        assert call_body["requiredPageNumber"] == 2

    def test_elements_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, ["catalogs", "elements", "cat-1"])
        assert result.exit_code == 0
        assert "nenhum" in result.stdout.lower()

    def test_elements_no_farm(self, runner, mock_settings, temp_state):
        result = runner.invoke(app, ["catalogs", "elements", "cat-1"])
        assert result.exit_code != 0
