"""Step definitions for plan_lifecycle_cli_coverage.feature.

Covers the five-panel output of _print_lifecycle_plan():
- Plan Status panel (Processing State, Projects, Action, Phase, Attempt)
- Progress panel (Strategize, Execute, Apply)
- Timing panel (Started, Elapsed, ETA, phase timestamps)
- Execution Detail panel (Sandbox, Tool Calls, Files Modified, Child Plans,
  Checkpoints)
- Cost panel (Tokens Used, Cost So Far, Estimated)
- Status refresh footer
- Optional fields: Arguments, Automation Profile, Estimation Actor,
  Invariant Actor
"""

from __future__ import annotations

from datetime import datetime, timedelta

from behave import when

from cleveragents.cli.commands.plan import app as plan_app
from cleveragents.domain.models.core.plan import (
    AutomationProfileProvenance,
    AutomationProfileRef,
    NamespacedName,
    Plan,
    PlanIdentity,
    PlanPhase,
    PlanTimestamps,
    ProcessingState,
    ProjectLink,
)

_PLAN_ULID = "01ARZ3NDEKTSV4RRFFQ69G5FBF"


def _make_five_panel_plan(
    *,
    arguments: dict[str, object] | None = None,
    arguments_order: list[str] | None = None,
    automation_profile: AutomationProfileRef | None = None,
    estimation_actor: str | None = None,
    invariant_actor: str | None = None,
    timestamps: PlanTimestamps | None = None,
) -> Plan:
    """Build a Plan with all fields needed for five-panel output testing."""
    now = datetime.now()
    if timestamps is None:
        timestamps = PlanTimestamps(
            created_at=now - timedelta(hours=1),
            updated_at=now,
        )
    return Plan(
        identity=PlanIdentity(plan_id=_PLAN_ULID),
        namespaced_name=NamespacedName.parse("local/five-panel-plan"),
        action_name="local/test-action",
        description="Five panel test plan",
        phase=PlanPhase.EXECUTE,
        processing_state=ProcessingState.PROCESSING,
        project_links=[
            ProjectLink(project_name="proj-a"),
            ProjectLink(project_name="proj-b"),
        ],
        arguments=dict(arguments) if arguments else {},
        arguments_order=arguments_order or [],
        automation_profile=automation_profile,
        estimation_actor=estimation_actor,
        invariant_actor=invariant_actor,
        reusable=True,
        read_only=False,
        timestamps=timestamps,
    )


@when("I run plan status for a plan with all five panels")
def step_plan_status_five_panels(context) -> None:
    """Run plan status for a plan that exercises all five output panels."""
    plan = _make_five_panel_plan()
    context.lifecycle_service.get_plan.return_value = plan
    context.result = context.runner.invoke(plan_app, ["status", _PLAN_ULID])


@when("I run plan status for a plan with arguments")
def step_plan_status_with_arguments(context) -> None:
    """Run plan status for a plan that has arguments."""
    plan = _make_five_panel_plan(
        arguments={"coverage": 80, "framework": "behave"},
        arguments_order=["coverage", "framework"],
    )
    context.lifecycle_service.get_plan.return_value = plan
    context.result = context.runner.invoke(plan_app, ["status", _PLAN_ULID])


@when("I run plan status for a plan with automation profile")
def step_plan_status_with_automation_profile(context) -> None:
    """Run plan status for a plan that has an automation profile."""
    plan = _make_five_panel_plan(
        automation_profile=AutomationProfileRef(
            profile_name="trusted",
            provenance=AutomationProfileProvenance.PLAN,
        ),
    )
    context.lifecycle_service.get_plan.return_value = plan
    context.result = context.runner.invoke(plan_app, ["status", _PLAN_ULID])


@when("I run plan status for a plan with estimation actor")
def step_plan_status_with_estimation_actor(context) -> None:
    """Run plan status for a plan that has an estimation actor."""
    plan = _make_five_panel_plan(estimation_actor="openai/gpt-4")
    context.lifecycle_service.get_plan.return_value = plan
    context.result = context.runner.invoke(plan_app, ["status", _PLAN_ULID])


@when("I run plan status for a plan with invariant actor")
def step_plan_status_with_invariant_actor(context) -> None:
    """Run plan status for a plan that has an invariant actor."""
    plan = _make_five_panel_plan(invariant_actor="openai/gpt-4")
    context.lifecycle_service.get_plan.return_value = plan
    context.result = context.runner.invoke(plan_app, ["status", _PLAN_ULID])


@when("I run plan status for a plan with all timestamps")
def step_plan_status_with_all_timestamps(context) -> None:
    """Run plan status for a plan that has all phase timestamps populated."""
    now = datetime.now()
    timestamps = PlanTimestamps(
        created_at=now - timedelta(hours=2),
        updated_at=now,
        strategize_started_at=now - timedelta(hours=1, minutes=50),
        strategize_completed_at=now - timedelta(hours=1, minutes=40),
        execute_started_at=now - timedelta(hours=1, minutes=30),
        execute_completed_at=now - timedelta(hours=1),
        applied_at=now - timedelta(minutes=30),
    )
    plan = _make_five_panel_plan(
        timestamps=timestamps,
    )
    context.lifecycle_service.get_plan.return_value = plan
    context.result = context.runner.invoke(plan_app, ["status", _PLAN_ULID])
