"""Step definitions for Plan Resume Service coverage boost tests.

Targets uncovered validation-error branches in PlanResumeService:
- Line 75:  __init__ with None lifecycle_service
- Line 93:  get_resume_metadata with empty plan_id
- Line 186: build_resume_summary with empty plan_id
- Line 303: record_step_checkpoint with empty plan_id
- Line 305: record_step_checkpoint with negative step_index
- Line 307: record_step_checkpoint with empty decision_id
- Line 309: record_step_checkpoint with empty step_text
- Line 354: record_shutdown with empty plan_id
- Line 384: set_total_steps with negative total
"""

from behave import given, then, when
from behave.runner import Context
from ulid import ULID

from cleveragents.application.services.plan_lifecycle_service import (
    PlanLifecycleService,
)
from cleveragents.application.services.plan_resume_service import (
    PlanResumeService,
)
from cleveragents.config.settings import Settings
from cleveragents.core.exceptions import ValidationError
from cleveragents.domain.models.core.plan import (
    ProjectLink,
)

# ---- Given steps ----


@given("I have a coverage-boost PlanResumeService")
def step_create_coverage_boost_service(context: Context) -> None:
    """Create a lifecycle service and a PlanResumeService for coverage tests."""
    settings = Settings()
    context.cb_lifecycle = PlanLifecycleService(settings=settings)
    context.cb_resume = PlanResumeService(lifecycle_service=context.cb_lifecycle)
    context.cb_error = None
    context.cb_plan_id = None


@given("I have a coverage-boost plan in execute phase")
def step_create_coverage_boost_plan(context: Context) -> None:
    """Create a plan in execute/processing state for checkpoint tests."""
    action_name = f"local/cb-test-{ULID()!s}"[:30].lower()
    context.cb_lifecycle.create_action(
        name=action_name,
        description="Coverage boost test action",
        definition_of_done="Step 1\nStep 2",
        strategy_actor="local/stub-strategy",
        execution_actor="local/stub-execute",
    )
    plan = context.cb_lifecycle.use_action(
        action_name=action_name,
        project_links=[ProjectLink(project_name="local/cb-proj")],
    )
    plan_id = plan.identity.plan_id

    # Advance to execute/processing
    context.cb_lifecycle.start_strategize(plan_id)
    p = context.cb_lifecycle.get_plan(plan_id)
    p.decision_root_id = str(ULID())
    context.cb_lifecycle._commit_plan(p)
    context.cb_lifecycle.complete_strategize(plan_id)
    context.cb_lifecycle.execute_plan(plan_id)
    context.cb_lifecycle.start_execute(plan_id)

    context.cb_plan_id = plan_id


# ---- When steps ----


@when("I try to create a PlanResumeService with None lifecycle_service")
def step_create_service_with_none(context: Context) -> None:
    """Attempt to create PlanResumeService with None."""
    context.cb_error = None
    try:
        PlanResumeService(lifecycle_service=None)  # type: ignore[arg-type]
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to get resume metadata with empty plan_id")
def step_get_metadata_empty_id(context: Context) -> None:
    """Attempt to get resume metadata with empty string."""
    context.cb_error = None
    try:
        context.cb_resume.get_resume_metadata("")
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to build resume summary with empty plan_id")
def step_build_summary_empty_id(context: Context) -> None:
    """Attempt to build resume summary with empty string."""
    context.cb_error = None
    try:
        context.cb_resume.build_resume_summary("")
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to record a step checkpoint with empty plan_id")
def step_checkpoint_empty_plan_id(context: Context) -> None:
    """Attempt to record checkpoint with empty plan_id."""
    context.cb_error = None
    try:
        context.cb_resume.record_step_checkpoint(
            plan_id="",
            step_index=0,
            decision_id="DEC001",
            step_text="Do something",
        )
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to record a step checkpoint with step_index {index:d}")
def step_checkpoint_negative_index(context: Context, index: int) -> None:
    """Attempt to record checkpoint with given step_index."""
    context.cb_error = None
    try:
        context.cb_resume.record_step_checkpoint(
            plan_id=context.cb_plan_id,
            step_index=index,
            decision_id="DEC001",
            step_text="Do something",
        )
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to record a step checkpoint with empty decision_id")
def step_checkpoint_empty_decision(context: Context) -> None:
    """Attempt to record checkpoint with empty decision_id."""
    context.cb_error = None
    try:
        context.cb_resume.record_step_checkpoint(
            plan_id=context.cb_plan_id,
            step_index=0,
            decision_id="",
            step_text="Do something",
        )
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to record a step checkpoint with empty step_text")
def step_checkpoint_empty_step_text(context: Context) -> None:
    """Attempt to record checkpoint with empty step_text."""
    context.cb_error = None
    try:
        context.cb_resume.record_step_checkpoint(
            plan_id=context.cb_plan_id,
            step_index=0,
            decision_id="DEC001",
            step_text="",
        )
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to record shutdown with empty plan_id")
def step_shutdown_empty_plan_id(context: Context) -> None:
    """Attempt to record shutdown with empty plan_id."""
    context.cb_error = None
    try:
        context.cb_resume.record_shutdown("")
    except ValidationError as exc:
        context.cb_error = exc


@when("I try to set total steps to {total:d}")
def step_set_total_steps_negative(context: Context, total: int) -> None:
    """Attempt to set total steps to given value."""
    context.cb_error = None
    try:
        context.cb_resume.set_total_steps(context.cb_plan_id, total)
    except ValidationError as exc:
        context.cb_error = exc


# ---- Then steps ----


@then('a coverage-boost ValidationError should be raised with message "{expected_msg}"')
def step_assert_validation_error_with_message(
    context: Context, expected_msg: str
) -> None:
    """Assert a ValidationError was raised and contains the expected message."""
    assert context.cb_error is not None, (
        "Expected a ValidationError but none was raised"
    )
    assert isinstance(context.cb_error, ValidationError), (
        f"Expected ValidationError, got {type(context.cb_error).__name__}"
    )
    assert expected_msg in str(context.cb_error), (
        f"Expected message containing '{expected_msg}', got: {context.cb_error}"
    )
