"""Step definitions for CLI plan and context workflow tests."""

import os
import shutil
import tempfile
from pathlib import Path

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


def add_cleanup(context: Context, handler):
    """Add a cleanup handler to the context."""
    if not hasattr(context, "_cleanup_handlers"):
        context._cleanup_handlers = []
    context._cleanup_handlers.append(handler)


@given("I have a minimal test environment")
def step_minimal_test_environment(context: Context) -> None:
    """Ensure we have a minimal test environment."""
    context.test_dir = None
    context.original_dir = os.getcwd()
    # Set up mock AI provider for testing
    os.environ["CLEVERAGENTS_TESTING_USE_MOCK_AI"] = "true"


@given("I am in a temporary directory")
def step_in_temp_directory(context: Context) -> None:
    """Create and change to a temporary directory."""
    context.test_dir = tempfile.mkdtemp(prefix="cleveragents_test_")
    context.original_dir = os.getcwd()
    previous_search_root = os.environ.get("CLEVERAGENTS_PROJECT_SEARCH_ROOT")
    os.environ["CLEVERAGENTS_PROJECT_SEARCH_ROOT"] = context.test_dir
    os.chdir(context.test_dir)

    # Register cleanup
    def cleanup():
        os.chdir(context.original_dir)
        if previous_search_root is None:
            os.environ.pop("CLEVERAGENTS_PROJECT_SEARCH_ROOT", None)
        else:
            os.environ["CLEVERAGENTS_PROJECT_SEARCH_ROOT"] = previous_search_root
        if context.test_dir and os.path.exists(context.test_dir):
            shutil.rmtree(context.test_dir)

    add_cleanup(context, cleanup)


@given('I have initialized a project "{name}"')
def step_initialize_project_simple(context: Context, name: str) -> None:
    """Initialize a project in the current directory.

    Uses in-process CLI invocation to avoid the ~6 s subprocess overhead.
    """
    from cleveragents.cli.commands.project import init_command

    prev_cwd = os.getcwd()
    target = (
        context.test_dir
        if hasattr(context, "test_dir") and context.test_dir
        else prev_cwd
    )
    os.chdir(target)
    try:
        init_command(name, Path(target))
    except Exception as exc:
        raise AssertionError(f"Failed to initialize project: {exc}") from exc
    finally:
        os.chdir(prev_cwd)


@given('I have created a file "{filename}" with content "{content}"')
def step_create_file_with_content(
    context: Context, filename: str, content: str
) -> None:
    """Create a file with specific content."""
    Path(filename).write_text(content)


@given('I have added path "{path}" to context')
def step_add_path_to_context(context: Context, path: str) -> None:
    """Add a file or directory path to context.

    Uses in-process CLI invocation to avoid subprocess overhead.
    """
    from cleveragents.cli.commands.context import context_add
    from cleveragents.cli.commands.plan import tell as plan_tell

    prev_cwd = os.getcwd()
    target = (
        context.test_dir
        if hasattr(context, "test_dir") and context.test_dir
        else prev_cwd
    )
    os.chdir(target)
    try:
        # First ensure we have a plan
        if not hasattr(context, "has_plan"):
            plan_tell(prompt="Default test plan")
            context.has_plan = True

        context_add(paths=[path], recursive=True)
    except Exception as exc:
        raise AssertionError(f"Failed to add to context: {exc}") from exc
    finally:
        os.chdir(prev_cwd)


@then('the directory "{dirname}" should exist')
def step_directory_should_exist(context: Context, dirname: str) -> None:
    """Check if a directory exists."""
    assert Path(dirname).is_dir(), f"Directory {dirname} does not exist"


@then('the test file "{filename}" should exist')
def step_test_file_should_exist(context: Context, filename: str) -> None:
    """Check if a test file exists."""
    assert Path(filename).exists(), f"File {filename} does not exist"


@then('the file "{filename}" should contain "{content}"')
def step_file_should_contain(context: Context, filename: str, content: str) -> None:
    """Check if a file contains specific content."""
    file_content = Path(filename).read_text()
    assert content in file_content, f"File {filename} does not contain '{content}'"


def after_scenario(context: Context, scenario) -> None:
    """Clean up after each scenario."""
    # Clean up environment variables
    if "CLEVERAGENTS_TESTING_USE_MOCK_AI" in os.environ:
        del os.environ["CLEVERAGENTS_TESTING_USE_MOCK_AI"]

    # Execute any cleanup handlers
    if hasattr(context, "_cleanup_handlers"):
        for handler in context._cleanup_handlers:
            handler()
