"""Step definitions for tui_persona_schema_coverage.feature.

These steps target specific uncovered lines in
cleveragents.tui.persona.schema:
- Line 39:  raise ValueError when actor is not namespaced
- Line 66:  raise ValueError when != 1 default preset
- Line 68:  raise ValueError when default preset has overrides
- Lines 73-82: effective_arguments method (all branches)
"""

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

from cleveragents.tui.persona.schema import Persona, PersonaPreset


# ---------------------------------------------------------------------------
# Background
# ---------------------------------------------------------------------------
@given("the persona schema module is imported")
def step_persona_schema_imported(context):
    """Verify the schema module is importable."""
    assert Persona is not None
    assert PersonaPreset is not None


# ---------------------------------------------------------------------------
# Helper to build minimal valid kwargs for Persona
# ---------------------------------------------------------------------------
def _base_kwargs(**overrides):
    """Return minimal valid Persona kwargs, merged with *overrides*."""
    defaults = {
        "name": "test-persona",
        "actor": "ns/actor",
    }
    defaults.update(overrides)
    return defaults


# ---------------------------------------------------------------------------
# Actor validation - line 39
# ---------------------------------------------------------------------------
@when('I create a Persona with actor "{actor}"')
def step_create_persona_bad_actor(context, actor):
    """Attempt to create a Persona with a given actor string."""
    try:
        context.persona_result = Persona(**_base_kwargs(actor=actor))
        context.persona_error = None
    except (ValidationError, ValueError) as exc:
        context.persona_result = None
        context.persona_error = exc


@then('tpschcov a ValueError should be raised with message containing "{fragment}"')
def step_assert_value_error_message(context, fragment):
    """Assert that a ValueError (or Pydantic ValidationError) was raised."""
    assert context.persona_error is not None, "Expected an error but none was raised"
    assert fragment in str(context.persona_error), (
        f"Expected '{fragment}' in error message, got: {context.persona_error}"
    )


# ---------------------------------------------------------------------------
# Multiple default presets - line 66
# ---------------------------------------------------------------------------
@when("I create a Persona with two default presets")
def step_create_persona_two_defaults(context):
    """Supply two presets both named 'default'."""
    presets = [
        PersonaPreset(name="default", display="Default 1", overrides={}),
        PersonaPreset(name="default", display="Default 2", overrides={}),
    ]
    try:
        context.persona_result = Persona(**_base_kwargs(argument_presets=presets))
        context.persona_error = None
    except (ValidationError, ValueError) as exc:
        context.persona_result = None
        context.persona_error = exc


@when("I create a Persona with presets but no default preset")
def step_create_persona_no_default_preset(context):
    """Supply presets where none is named 'default'."""
    presets = [
        PersonaPreset(name="fast", display="Fast", overrides={"speed": 10}),
    ]
    try:
        context.persona_result = Persona(**_base_kwargs(argument_presets=presets))
        context.persona_error = None
    except (ValidationError, ValueError) as exc:
        context.persona_result = None
        context.persona_error = exc


# ---------------------------------------------------------------------------
# Default preset with non-empty overrides - line 68
# ---------------------------------------------------------------------------
@when("I create a Persona whose default preset has overrides")
def step_create_persona_default_preset_with_overrides(context):
    """Supply a single default preset that has non-empty overrides."""
    presets = [
        PersonaPreset(name="default", display="Default", overrides={"key": "val"}),
    ]
    try:
        context.persona_result = Persona(**_base_kwargs(argument_presets=presets))
        context.persona_error = None
    except (ValidationError, ValueError) as exc:
        context.persona_result = None
        context.persona_error = exc


# ---------------------------------------------------------------------------
# effective_arguments - lines 73-82
# ---------------------------------------------------------------------------
@given("I have a valid Persona with base arguments")
def step_persona_with_base_args(context):
    """Create a Persona that has base_arguments set."""
    context.test_persona = Persona(
        **_base_kwargs(base_arguments={"model": "gpt-4", "temp": 0.7})
    )


@given("I have a valid Persona with base arguments and a custom preset")
def step_persona_with_base_args_and_preset(context):
    """Create a Persona with base_arguments and a custom 'fast' preset."""
    presets = [
        PersonaPreset(name="default", display="Default", overrides={}),
        PersonaPreset(name="fast", display="Fast", overrides={"temp": 0.1, "top_k": 5}),
    ]
    context.test_persona = Persona(
        **_base_kwargs(
            base_arguments={"model": "gpt-4", "temp": 0.7},
            argument_presets=presets,
        )
    )


@when("I call effective_arguments with no preset name")
def step_call_effective_no_preset(context):
    """Call effective_arguments() without a preset name."""
    context.effective_result = context.test_persona.effective_arguments()


@when('I call effective_arguments with preset name "{preset_name}"')
def step_call_effective_with_preset(context, preset_name):
    """Call effective_arguments(preset_name)."""
    context.effective_result = context.test_persona.effective_arguments(preset_name)


@then("the result should equal the base arguments")
def step_assert_equals_base_args(context):
    """Verify the result is a copy of base_arguments."""
    expected = dict(context.test_persona.base_arguments)
    assert context.effective_result == expected, (
        f"Expected {expected}, got {context.effective_result}"
    )


@then("the result should contain the base arguments merged with the preset overrides")
def step_assert_merged_args(context):
    """Verify base_arguments are shallow-merged with the preset overrides."""
    expected = {"model": "gpt-4", "temp": 0.1, "top_k": 5}
    assert context.effective_result == expected, (
        f"Expected {expected}, got {context.effective_result}"
    )
