"""Tests for SettingsManager._create_setting metadata inference.

_create_setting infers category, ui_element, and other metadata from key
patterns and value types during bulk import operations.
"""

from unittest.mock import MagicMock

import pytest


class TestCreateSettingCategoryInference:
    """Tests for _create_setting category determination from key prefix."""

    @pytest.fixture
    def mock_manager(self):
        """Create a mock SettingsManager with _create_setting accessible."""
        from enum import Enum

        class MockSettingType(Enum):
            DATABASE = "database"

        from local_deep_research.settings.manager import SettingsManager

        manager = MagicMock()
        manager._create_setting = SettingsManager._create_setting.__get__(
            manager, type(manager)
        )
        return manager, MockSettingType.DATABASE

    def test_app_prefix_category(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.theme", "dark", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "app_interface"
        )

    def test_llm_temperature_gets_parameters_category(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("llm.temperature", 0.7, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "llm_parameters"
        )

    def test_llm_max_tokens_gets_parameters_category(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("llm.max_tokens", 4096, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "llm_parameters"
        )

    def test_llm_general_setting(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("llm.provider", "openai", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "llm_general"
        )

    def test_search_iterations_gets_parameters(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("search.iterations", 3, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "search_parameters"
        )

    def test_search_questions_gets_parameters(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("search.questions", 5, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "search_parameters"
        )

    def test_search_general_setting(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("search.engine", "ddg", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "search_general"
        )

    def test_report_prefix_category(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("report.format", "pdf", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"]
            == "report_parameters"
        )

    def test_unknown_prefix_gets_none(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("custom.setting", "val", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["category"] is None
        )


class TestCreateSettingUIElementInference:
    """Tests for _create_setting UI element inference from value types."""

    @pytest.fixture
    def mock_manager(self):
        from enum import Enum

        class MockSettingType(Enum):
            DATABASE = "database"

        from local_deep_research.settings.manager import SettingsManager

        manager = MagicMock()
        manager._create_setting = SettingsManager._create_setting.__get__(
            manager, type(manager)
        )
        return manager, MockSettingType.DATABASE

    def test_bool_value_checkbox(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.enabled", True, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["ui_element"]
            == "checkbox"
        )

    def test_int_value_number(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.count", 42, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["ui_element"]
            == "number"
        )

    def test_float_value_number(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.ratio", 0.5, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["ui_element"]
            == "number"
        )

    def test_dict_value_json(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.config", {"k": "v"}, st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["ui_element"]
            == "json"
        )

    def test_list_value_json(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.items", [1, 2], st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["ui_element"]
            == "json"
        )

    def test_string_value_text(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.name", "hello", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["ui_element"]
            == "text"
        )


class TestCreateSettingNameDerivation:
    """Tests for setting name and description generation."""

    @pytest.fixture
    def mock_manager(self):
        from enum import Enum

        class MockSettingType(Enum):
            DATABASE = "database"

        from local_deep_research.settings.manager import SettingsManager

        manager = MagicMock()
        manager._create_setting = SettingsManager._create_setting.__get__(
            manager, type(manager)
        )
        return manager, MockSettingType.DATABASE

    def test_name_from_last_segment(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("llm.model_name", "gpt-4", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["name"]
            == "Model Name"
        )

    def test_description_includes_key(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.theme", "dark", st)
        assert (
            "app.theme"
            in manager.create_or_update_setting.call_args[0][0]["description"]
        )

    def test_key_stored_correctly(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("search.engine", "ddg", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["key"]
            == "search.engine"
        )

    def test_value_stored_correctly(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.flag", True, st)
        assert manager.create_or_update_setting.call_args[0][0]["value"] is True

    def test_type_stored_as_lowercase(self, mock_manager):
        manager, st = mock_manager
        manager._create_setting("app.x", "v", st)
        assert (
            manager.create_or_update_setting.call_args[0][0]["type"]
            == "database"
        )
