"""Tests for DropdownResolver utility."""

import pytest

from concentriq.metadata import DropdownResolver


DROPDOWN_FIELD = {
    "id": 2,
    "name": "Status",
    "contentType": "dropdown",
    "resourceType": "image",
    "dropdownOptions": [
        {"id": 10, "value": "Active"},
        {"id": 11, "value": "Inactive"},
        {"id": 12, "value": "Pending Review"},
    ],
}

FIELD_NO_OPTIONS = {
    "id": 3,
    "name": "Empty Dropdown",
    "contentType": "dropdown",
    "resourceType": "image",
    "dropdownOptions": [],
}

NON_DROPDOWN_FIELD = {
    "id": 1,
    "name": "Diagnosis",
    "contentType": "string",
    "resourceType": "image",
}


class TestDropdownResolverToId:
    """Tests for DropdownResolver.to_id() — text to option ID."""

    def test_to_id_returns_option_id_for_matching_value(self):
        """Should return the numeric option ID for an exact text match."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        assert resolver.to_id("Active") == 10
        assert resolver.to_id("Inactive") == 11
        assert resolver.to_id("Pending Review") == 12

    def test_to_id_raises_for_unknown_value(self):
        """Should raise KeyError when the text doesn't match any option."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        with pytest.raises(KeyError):
            resolver.to_id("Nonexistent")

    def test_to_id_is_case_sensitive(self):
        """Should not match options with different casing."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        with pytest.raises(KeyError):
            resolver.to_id("active")


class TestDropdownResolverToValue:
    """Tests for DropdownResolver.to_value() — option ID to text."""

    def test_to_value_returns_text_for_matching_id(self):
        """Should return the option text for a matching numeric ID."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        assert resolver.to_value(10) == "Active"
        assert resolver.to_value(11) == "Inactive"
        assert resolver.to_value(12) == "Pending Review"

    def test_to_value_raises_for_unknown_id(self):
        """Should raise KeyError when the ID doesn't match any option."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        with pytest.raises(KeyError):
            resolver.to_value(999)


class TestDropdownResolverOptions:
    """Tests for DropdownResolver informational properties."""

    def test_options_returns_all_options(self):
        """Should expose all available options as id-value pairs."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        options = resolver.options
        assert len(options) == 3
        assert {"id": 10, "value": "Active"} in options

    def test_values_returns_all_option_texts(self):
        """Should return a list of all option text values."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        assert set(resolver.values) == {"Active", "Inactive", "Pending Review"}

    def test_empty_dropdown_has_no_options(self):
        """Should handle a dropdown field with no options."""
        resolver = DropdownResolver(FIELD_NO_OPTIONS)
        assert resolver.options == []
        assert resolver.values == []

    def test_field_name_is_accessible(self):
        """Should expose the field name for error messages and debugging."""
        resolver = DropdownResolver(DROPDOWN_FIELD)
        assert resolver.field_name == "Status"
