"""Tests for PowerPathClient initialization and configuration."""

import os
from unittest.mock import patch

import pytest

from timeback_powerpath import PowerPathClient


class TestPowerPathClientInit:
    """Tests for client initialization."""

    def test_staging_environment(self):
        """Staging environment should use staging URL."""
        client = PowerPathClient(env="staging", client_id="id", client_secret="secret")
        assert "staging" in client._transport.base_url

    def test_production_environment(self):
        """Production environment should use production URL."""
        client = PowerPathClient(env="production", client_id="id", client_secret="secret")
        assert "dev" not in client._transport.base_url
        assert "staging" not in client._transport.base_url

    def test_custom_base_url(self):
        """Custom base URL should override environment."""
        with patch.dict(
            os.environ,
            {
                "POWERPATH_CLIENT_ID": "id",
                "POWERPATH_CLIENT_SECRET": "secret",
                "POWERPATH_TOKEN_URL": "https://auth.example.com/oauth2/token",
            },
        ):
            client = PowerPathClient(
                base_url="https://custom.example.com",
                auth_url="https://auth.example.com/oauth2/token",
            )
            assert client._transport.base_url == "https://custom.example.com"

    def test_explicit_credentials(self):
        """Explicit credentials should work."""
        client = PowerPathClient(
            env="staging",
            client_id="my-id",
            client_secret="my-secret",
        )
        assert client._provider is not None
        tm = client._provider.get_token_manager("powerpath")
        assert tm is not None
        assert tm._config.client_id == "my-id"
        assert tm._config.client_secret == "my-secret"

    def test_missing_credentials_raises(self):
        """Missing credentials should raise ValueError."""
        with patch.dict(os.environ, {}, clear=True):
            os.environ.pop("POWERPATH_CLIENT_ID", None)
            os.environ.pop("POWERPATH_CLIENT_SECRET", None)
            os.environ.pop("TIMEBACK_API_CLIENT_ID", None)
            os.environ.pop("TIMEBACK_API_CLIENT_SECRET", None)
            os.environ.pop("TIMEBACK_CLIENT_ID", None)
            os.environ.pop("TIMEBACK_CLIENT_SECRET", None)
            with pytest.raises(ValueError, match="Missing required environment variable"):
                PowerPathClient(env="staging")

    def test_default_platform_is_beyond_ai(self):
        """Default platform should be BEYOND_AI."""
        client = PowerPathClient(env="staging", client_id="id", client_secret="secret")
        assert "alpha-1edtech" in client._transport.base_url

    def test_beyond_ai_platform(self):
        """BEYOND_AI platform should succeed."""
        client = PowerPathClient(
            platform="BEYOND_AI",
            env="staging",
            client_id="id",
            client_secret="secret",
        )
        assert client._transport.base_url is not None

    def test_custom_provider(self):
        """Custom provider should work."""
        client = PowerPathClient(
            base_url="https://custom.api.com",
            auth_url="https://custom.auth.com/token",
            client_id="test-id",
            client_secret="test-secret",
        )
        assert client._transport.base_url == "https://custom.api.com"


class TestPowerPathClientResources:
    """Tests for client resource initialization."""

    def test_all_resources_initialized(self):
        """Client should initialize all resources."""
        client = PowerPathClient(env="staging", client_id="id", client_secret="secret")

        assert hasattr(client, "assessments")
        assert hasattr(client, "lesson_plans")
        assert hasattr(client, "placement")
        assert hasattr(client, "screening")
        assert hasattr(client, "syllabus")
        assert hasattr(client, "test_assignments")


class TestPowerPathClientTransport:
    """Tests for transport access."""

    def test_get_transport(self):
        """Client should expose transport via get_transport()."""
        client = PowerPathClient(env="staging", client_id="id", client_secret="secret")

        transport = client.get_transport()
        assert transport is not None
        assert transport.base_url is not None


class TestPowerPathClientCheckAuth:
    """Tests for check_auth."""

    @pytest.mark.asyncio
    async def test_check_auth_raises_without_provider(self):
        """check_auth should raise when no provider is set (custom transport)."""
        from timeback_common import PowerPathPaths

        class MockTransport:
            base_url = "https://mock.api.com"
            paths = PowerPathPaths()

            async def close(self) -> None:
                pass

        client = PowerPathClient(transport=MockTransport())

        with pytest.raises(RuntimeError, match="Cannot check auth"):
            await client.check_auth()

    def test_custom_transport_without_paths_raises(self):
        """Custom transport without paths should raise TypeError."""

        class BadTransport:
            base_url = "https://mock.api.com"

            async def close(self) -> None:
                pass

        with pytest.raises(TypeError, match="paths"):
            PowerPathClient(transport=BadTransport())


class TestPowerPathClientContextManager:
    """Tests for context manager support."""

    @pytest.mark.asyncio
    async def test_context_manager(self):
        """Client should work as async context manager."""
        async with PowerPathClient(env="staging", client_id="id", client_secret="secret") as client:
            assert client._provider is not None
