"""Step definitions for plan resume fields persistence feature.

Tests round-trip persistence of reversion_count, last_completed_step,
and last_checkpoint_id through the LifecyclePlanRepository.

Background steps (fresh in-memory DB, prerequisite action, file-based DB,
close-and-reopen, new lifecycle plan, persist plan) are reused from
plan_persistence_steps.py — they share the same step text so Behave
automatically picks them up.
"""

from __future__ import annotations

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

# ---------------------------------------------------------------------------
# Given: mutate the plan under test
# ---------------------------------------------------------------------------


@given("the plan has reversion_count {count:d}")
def step_plan_has_reversion_count(context: Context, count: int) -> None:
    """Set reversion_count on the plan being built."""
    context._pp_plan = context._pp_plan.model_copy(update={"reversion_count": count})


@given("the plan has last_completed_step {step:d}")
def step_plan_has_last_completed_step(context: Context, step: int) -> None:
    """Set last_completed_step on the plan being built."""
    context._pp_plan = context._pp_plan.model_copy(update={"last_completed_step": step})


@given('the plan has last_checkpoint_id "{checkpoint_id}"')
def step_plan_has_last_checkpoint_id(context: Context, checkpoint_id: str) -> None:
    """Set last_checkpoint_id on the plan being built."""
    context._pp_plan = context._pp_plan.model_copy(
        update={"last_checkpoint_id": checkpoint_id}
    )


# ---------------------------------------------------------------------------
# When: retrieve the plan
# ---------------------------------------------------------------------------


@when('I retrieve the plan by ID "{plan_id}"')
def step_retrieve_plan_by_id(context: Context, plan_id: str) -> None:
    """Retrieve the plan from the repository and store it for assertions."""
    context.retrieved_plan = context._pp_plan_repo.get(plan_id)
    assert context.retrieved_plan is not None, (
        f"Plan {plan_id!r} not found in repository"
    )


# ---------------------------------------------------------------------------
# When: update reversion_count on an already-persisted plan
# ---------------------------------------------------------------------------


@when("I update the plan reversion_count to {count:d}")
def step_update_plan_reversion_count(context: Context, count: int) -> None:
    """Update reversion_count on the persisted plan.

    Uses ``context._pp_plan`` (the plan that was just persisted) so this
    step can be called immediately after "I persist the plan via the plan
    repository" without a prior retrieve step.
    """
    updated = context._pp_plan.model_copy(update={"reversion_count": count})
    context._pp_plan_repo.update(updated)
    context._pp_session.commit()


# ---------------------------------------------------------------------------
# Then: assert resume field values
# ---------------------------------------------------------------------------


@then("the retrieved plan reversion_count should be {count:d}")
def step_retrieved_plan_reversion_count(context: Context, count: int) -> None:
    """Assert the retrieved plan's reversion_count."""
    assert context.retrieved_plan.reversion_count == count, (
        f"Expected reversion_count={count}, got {context.retrieved_plan.reversion_count}"
    )


@then("the retrieved plan last_completed_step should be {step:d}")
def step_retrieved_plan_last_completed_step(context: Context, step: int) -> None:
    """Assert the retrieved plan's last_completed_step."""
    assert context.retrieved_plan.last_completed_step == step, (
        f"Expected last_completed_step={step}, "
        f"got {context.retrieved_plan.last_completed_step}"
    )


@then('the retrieved plan last_checkpoint_id should be "{checkpoint_id}"')
def step_retrieved_plan_last_checkpoint_id(
    context: Context, checkpoint_id: str
) -> None:
    """Assert the retrieved plan's last_checkpoint_id matches the expected value."""
    assert context.retrieved_plan.last_checkpoint_id == checkpoint_id, (
        f"Expected last_checkpoint_id={checkpoint_id!r}, "
        f"got {context.retrieved_plan.last_checkpoint_id!r}"
    )


@then("the retrieved plan last_checkpoint_id should be None")
def step_retrieved_plan_last_checkpoint_id_none(context: Context) -> None:
    """Assert the retrieved plan's last_checkpoint_id is None."""
    assert context.retrieved_plan.last_checkpoint_id is None, (
        f"Expected last_checkpoint_id=None, "
        f"got {context.retrieved_plan.last_checkpoint_id!r}"
    )
