"""Step definitions for AI Models Credentials coverage tests."""

from behave import given, then, when
from pydantic import ValidationError

from cleveragents.domain.models.aimodelsproviders.ai_models_providers import (
    ModelProviderConfigSchema,
)
from cleveragents.domain.models.core.enums import ModelPublisher


@given("the cleveragents package is available")
def step_package_available(context):
    """Verify the cleveragents package is available."""
    import cleveragents

    assert cleveragents is not None


@when("I import ModelProviderOption from aimodelscredentials")
def step_import_model_provider_option(context):
    """Import ModelProviderOption class."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    context.model_provider_option_class = ModelProviderOption
    context.imported_class = ModelProviderOption


@then("the ModelProviderOption class should be available")
def step_verify_class_available(context):
    """Verify ModelProviderOption class is available."""
    assert context.model_provider_option_class is not None
    assert context.model_provider_option_class.__name__ == "ModelProviderOption"


@then("I can create a ModelProviderOption with publishers, config, and priority")
def step_create_full_model(context):
    """Create a ModelProviderOption with all fields."""
    ModelProviderOption = context.model_provider_option_class

    # Create a sample config
    from cleveragents.domain.models.core.enums import ModelProvider

    config = ModelProviderConfigSchema(
        provider=ModelProvider.OPENAI, baseUrl="https://api.openai.com/v1"
    )

    # Create publishers dictionary
    publishers = {
        "provider1": {ModelPublisher.OPENAI: True, ModelPublisher.ANTHROPIC: False},
        "provider2": {ModelPublisher.GOOGLE: True},
    }

    # Create the model
    model = ModelProviderOption(publishers=publishers, config=config, priority=1)

    assert model.priority == 1
    assert model.publishers == publishers
    assert model.config == config


@when("I create a ModelProviderOption with only priority set to {priority:d}")
def step_create_minimal_model(context, priority):
    """Create a ModelProviderOption with minimal fields."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    context.model_instance = ModelProviderOption(priority=priority)


@then("the ModelProviderOption should have priority {priority:d}")
def step_verify_priority(context, priority):
    """Verify the priority field value."""
    assert context.model_instance.priority == priority


@then("the publishers dictionary should be empty")
def step_verify_publishers_empty(context):
    """Verify publishers dictionary is empty."""
    assert context.model_instance.publishers == {}


@then("the config should be None")
def step_verify_config_none(context):
    """Verify config is None."""
    assert context.model_instance.config is None


@when("I create a ModelProviderOption with complex publishers structure")
def step_create_complex_publishers(context):
    """Create a ModelProviderOption with complex publishers."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    publishers = {
        "primary": {
            ModelPublisher.OPENAI: True,
            ModelPublisher.ANTHROPIC: True,
            ModelPublisher.GOOGLE: False,
        },
        "secondary": {ModelPublisher.MISTRAL: True, ModelPublisher.PERPLEXITY: False},
        "tertiary": {ModelPublisher.OPENAI: False},
    }

    context.model_instance = ModelProviderOption(publishers=publishers, priority=2)
    context.expected_publishers = publishers


@then("the publishers field should contain the expected dictionary structure")
def step_verify_publishers_structure(context):
    """Verify the publishers structure."""
    assert context.model_instance.publishers == context.expected_publishers


@then("the ModelPublisher enum values should be properly handled")
def step_verify_enum_handling(context):
    """Verify enum values are handled correctly."""
    # Check that enum values are properly stored
    for _provider, publisher_dict in context.model_instance.publishers.items():
        for _publisher, enabled in publisher_dict.items():
            # With use_enum_values=True, the enum values should be used
            assert isinstance(enabled, bool)


@when("I create a ModelProviderOption with a config object")
def step_create_with_config(context):
    """Create a ModelProviderOption with config."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )
    from cleveragents.domain.models.core.enums import ModelProvider

    config = ModelProviderConfigSchema(
        provider=ModelProvider.OPENAI, baseUrl="https://api.openai.com/v1"
    )

    context.model_instance = ModelProviderOption(config=config, priority=3)
    context.expected_config = config


@then("the config field should contain the ModelProviderConfigSchema instance")
def step_verify_config_instance(context):
    """Verify config contains the right instance."""
    assert context.model_instance.config == context.expected_config


@then("the config should be properly validated")
def step_verify_config_validated(context):
    """Verify config is validated."""
    from cleveragents.domain.models.core.enums import ModelProvider

    assert context.model_instance.config.provider == ModelProvider.OPENAI
    assert context.model_instance.config.base_url == "https://api.openai.com/v1"


@when("I create a ModelProviderOption with strings containing whitespace")
def step_create_with_whitespace(context):
    """Create model with whitespace in strings."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    # Note: The model doesn't have direct string fields, but we'll test with config
    from cleveragents.domain.models.core.enums import ModelProvider

    config = ModelProviderConfigSchema(
        provider=ModelProvider.OPENAI, baseUrl="  https://api.openai.com/v1  "
    )

    context.model_instance = ModelProviderOption(config=config, priority=4)


@then("the string fields should have whitespace stripped")
def step_verify_whitespace_stripped(context):
    """Verify whitespace is stripped from strings."""
    # The ModelProviderConfigSchema should handle its own whitespace stripping
    # based on its model_config settings
    assert context.model_instance.config.base_url == "https://api.openai.com/v1"


@when("I create a ModelProviderOption instance")
def step_create_instance(context):
    """Create a basic ModelProviderOption instance."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    context.model_instance = ModelProviderOption(priority=5)


@when("I update its fields with new values")
def step_update_fields(context):
    """Update model fields with new values."""
    context.model_instance.priority = 10
    context.model_instance.publishers = {"updated": {ModelPublisher.OPENAI: True}}


@then("the assignment validation should be triggered")
def step_verify_assignment_validation(context):
    """Verify assignment validation works."""
    # The values should be updated and validated
    assert context.model_instance.priority == 10


@then("the values should be properly validated")
def step_verify_values_validated(context):
    """Verify values are validated on assignment."""
    assert context.model_instance.publishers == {
        "updated": {ModelPublisher.OPENAI: True}
    }


@when("I create a ModelProviderOption using field aliases")
def step_create_with_aliases(context):
    """Create model using field aliases (populate_by_name)."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    # With populate_by_name=True, we can use field names directly
    data = {"priority": 6, "publishers": {}, "config": None}

    context.model_instance = ModelProviderOption(**data)


@then("the fields should be populated correctly by name")
def step_verify_populate_by_name(context):
    """Verify fields are populated by name."""
    assert context.model_instance.priority == 6
    assert context.model_instance.publishers == {}
    assert context.model_instance.config is None


@when("I create a ModelProviderOption with ModelPublisher enums")
def step_create_with_enums(context):
    """Create model with enum values."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    publishers = {
        "test": {ModelPublisher.OPENAI: True, ModelPublisher.ANTHROPIC: False}
    }

    context.model_instance = ModelProviderOption(publishers=publishers, priority=7)


@then("the enum values should be used in serialization")
def step_verify_enum_serialization(context):
    """Verify enum values in serialization."""
    data = context.model_instance.model_dump()
    # With use_enum_values=True, enums should be serialized as their values
    assert isinstance(data["publishers"], dict)


@then("the model should handle enum values properly")
def step_verify_enum_handling_proper(context):
    """Verify proper enum handling."""
    # The model should work with enum values
    assert context.model_instance.publishers["test"][ModelPublisher.OPENAI] is True


@when("I create a ModelProviderOption with default fields")
def step_create_with_defaults(context):
    """Create model with default fields."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    context.model_instance = ModelProviderOption(priority=8)


@then("publishers should default to an empty dictionary")
def step_verify_publishers_default(context):
    """Verify publishers defaults to empty dict."""
    assert context.model_instance.publishers == {}


@then("config should default to None")
def step_verify_config_default(context):
    """Verify config defaults to None."""
    assert context.model_instance.config is None


@when("I try to create a ModelProviderOption with invalid priority")
def step_create_invalid_priority(context):
    """Try to create model with invalid priority."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    try:
        # Priority should be an integer, not a string
        context.model_instance = ModelProviderOption(priority="invalid")
        context.validation_error = None
    except ValidationError as e:
        context.validation_error = e


@then("a ModelProviderOption validation error should be raised")
def step_verify_validation_error(context):
    """Verify validation error is raised."""
    assert context.validation_error is not None


@then("the error should indicate the priority field issue")
def step_verify_priority_error(context):
    """Verify error is about priority field."""
    error_dict = context.validation_error.errors()[0]
    assert "priority" in str(error_dict)


@when("I examine the ModelProviderOption model_config")
def step_examine_model_config(context):
    """Examine the model_config settings."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    context.model_config = ModelProviderOption.model_config


@then("the ModelProviderOption str_strip_whitespace should be True")
def step_verify_strip_whitespace_mpo(context):
    """Verify str_strip_whitespace setting for ModelProviderOption."""
    cfg = getattr(context, "model_config", None) or context.model_instance.model_config
    assert cfg.get("str_strip_whitespace") is True


@then("the ModelProviderOption validate_assignment should be True")
def step_verify_validate_assignment_mpo(context):
    """Verify validate_assignment setting for ModelProviderOption."""
    cfg = getattr(context, "model_config", None) or context.model_instance.model_config
    assert cfg.get("validate_assignment") is True


@then("the ModelProviderOption arbitrary_types_allowed should be False")
def step_verify_arbitrary_types_mpo(context):
    """Verify arbitrary_types_allowed setting for ModelProviderOption."""
    cfg = getattr(context, "model_config", None) or context.model_instance.model_config
    assert cfg.get("arbitrary_types_allowed") is False


@then("the ModelProviderOption populate_by_name should be True")
def step_verify_populate_by_name_setting_mpo(context):
    """Verify populate_by_name setting for ModelProviderOption."""
    cfg = getattr(context, "model_config", None) or context.model_instance.model_config
    assert cfg.get("populate_by_name") is True


@then("the ModelProviderOption use_enum_values should be True")
def step_verify_use_enum_values_mpo(context):
    """Verify use_enum_values setting for ModelProviderOption."""
    cfg = getattr(context, "model_config", None) or context.model_instance.model_config
    assert cfg.get("use_enum_values") is True


@when("I create a ModelProviderOption with nested publisher dictionaries")
def step_create_nested_publishers(context):
    """Create model with nested publisher structures."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    publishers = {
        "level1": {ModelPublisher.OPENAI: True, ModelPublisher.ANTHROPIC: False},
        "level2": {ModelPublisher.GOOGLE: True, ModelPublisher.MISTRAL: True},
    }

    context.model_instance = ModelProviderOption(publishers=publishers, priority=9)
    context.nested_publishers = publishers


@then("the nested structure should be properly maintained")
def step_verify_nested_structure(context):
    """Verify nested structure is maintained."""
    assert context.model_instance.publishers == context.nested_publishers


@then("the ModelPublisher boolean values should work correctly")
def step_verify_boolean_values(context):
    """Verify boolean values work correctly."""
    assert context.model_instance.publishers["level1"][ModelPublisher.OPENAI] is True
    assert (
        context.model_instance.publishers["level1"][ModelPublisher.ANTHROPIC] is False
    )
    assert context.model_instance.publishers["level2"][ModelPublisher.GOOGLE] is True


@when("I serialize a ModelProviderOption to dict")
def step_serialize_to_dict(context):
    """Serialize ModelProviderOption to dictionary."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )
    from cleveragents.domain.models.core.enums import ModelProvider

    config = ModelProviderConfigSchema(
        provider=ModelProvider.OPENAI, baseUrl="https://api.openai.com/v1"
    )

    model = ModelProviderOption(
        publishers={"test": {ModelPublisher.OPENAI: True}}, config=config, priority=10
    )

    context.original_model = model
    context.serialized_data = model.model_dump()


@when("I deserialize it back to ModelProviderOption")
def step_deserialize_from_dict(context):
    """Deserialize dictionary back to ModelProviderOption."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    context.deserialized_model = ModelProviderOption(**context.serialized_data)


@then("the round-trip should preserve all data")
def step_verify_round_trip(context):
    """Verify round-trip preserves data."""
    assert context.deserialized_model.priority == context.original_model.priority
    # Note: Direct comparison might fail due to enum serialization
    assert (
        context.deserialized_model.model_dump() == context.original_model.model_dump()
    )


@when("I explicitly set config to None in ModelProviderOption")
def step_set_config_none(context):
    """Explicitly set config to None."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    context.model_instance = ModelProviderOption(config=None, priority=11)


@then("the config field should accept None value")
def step_verify_config_accepts_none(context):
    """Verify config accepts None."""
    assert context.model_instance.config is None


@then("the model should be valid")
def step_verify_model_valid(context):
    """Verify model is valid."""
    # Model should be valid with None config
    assert context.model_instance.priority == 11


@when("I try to create a ModelProviderOption without priority")
def step_create_without_priority(context):
    """Try to create model without required priority field."""
    from cleveragents.domain.models.aimodelscredentials.ai_models_credentials import (
        ModelProviderOption,
    )

    try:
        context.model_instance = ModelProviderOption()
        context.validation_error = None
    except ValidationError as e:
        context.validation_error = e


@then(
    "a ModelProviderOption validation error should be raised for missing required field"
)
def step_verify_missing_field_error(context):
    """Verify error for missing required field."""
    assert context.validation_error is not None
    error_dict = context.validation_error.errors()[0]
    assert "priority" in str(error_dict)
    assert "required" in str(error_dict).lower() or "missing" in str(error_dict).lower()
