import pytest

from py_agent.api.py_agent import PyAgent
from py_agent.config import PyAgentConfig

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def make_agent(api_key: str | None = None) -> PyAgent:
    """Return a fresh PyAgent, optionally pre-seeded with an api_key."""
    config = PyAgentConfig(api_key=api_key)
    return PyAgent(config=config)


# ---------------------------------------------------------------------------
# Tests
# ---------------------------------------------------------------------------


class TestInitSetsInitializedFlag:
    @pytest.mark.asyncio
    async def test_initialized_false_before_init(self) -> None:
        """_initialized starts as False before init() is called."""
        agent = make_agent()
        assert agent._initialized is False

    @pytest.mark.asyncio
    async def test_initialized_true_after_init_no_key(self) -> None:
        """init() with no argument sets _initialized to True."""
        agent = make_agent()
        await agent.init()
        assert agent._initialized is True

    @pytest.mark.asyncio
    async def test_initialized_true_after_init_with_key(self) -> None:
        """init() with a valid api_key sets _initialized to True."""
        agent = make_agent()
        await agent.init(api_key="test-key-123")
        assert agent._initialized is True


class TestInitApiKeyHandling:
    @pytest.mark.asyncio
    async def test_api_key_set_when_provided(self) -> None:
        """init() with a truthy api_key stores it on the config."""
        agent = make_agent()
        await agent.init(api_key="my-secret-key")
        assert agent._config.api_key == "my-secret-key"

    @pytest.mark.asyncio
    async def test_api_key_not_overwritten_when_none(self) -> None:
        """Passing api_key=None leaves any existing config api_key untouched."""
        agent = make_agent(api_key="pre-existing-key")
        await agent.init(api_key=None)
        assert agent._config.api_key == "pre-existing-key"

    @pytest.mark.asyncio
    async def test_api_key_not_overwritten_when_empty_string(self) -> None:
        """Passing an empty string (falsy) leaves any existing config api_key untouched."""
        agent = make_agent(api_key="pre-existing-key")
        await agent.init(api_key="")
        assert agent._config.api_key == "pre-existing-key"

    @pytest.mark.asyncio
    async def test_api_key_none_when_not_provided_and_config_has_no_key(self) -> None:
        """init() with no api_key and a blank config leaves config.api_key as None."""
        agent = make_agent()
        await agent.init()
        assert agent._config.api_key is None

    @pytest.mark.asyncio
    async def test_api_key_overwritten_when_new_key_provided(self) -> None:
        """init() replaces an existing api_key with a new truthy value."""
        agent = make_agent(api_key="old-key")
        await agent.init(api_key="new-key")
        assert agent._config.api_key == "new-key"


class TestInitMiscBehaviour:
    @pytest.mark.asyncio
    async def test_init_returns_none(self) -> None:
        """init() is an async function that returns None."""
        agent = make_agent()
        result = await agent.init()
        assert result is None

    @pytest.mark.asyncio
    async def test_init_is_idempotent(self) -> None:
        """Calling init() twice keeps _initialized True and preserves api_key."""
        agent = make_agent()
        await agent.init(api_key="key-first-call")
        await agent.init()
        assert agent._initialized is True
        assert agent._config.api_key == "key-first-call"

    @pytest.mark.asyncio
    async def test_init_uses_default_config_when_none_passed_to_constructor(
        self,
    ) -> None:
        """PyAgent created without a config gets a default PyAgentConfig; init() still works."""
        agent = PyAgent()
        await agent.init(api_key="standalone-key")
        assert agent._initialized is True
        assert agent._config.api_key == "standalone-key"
