"""Integration test: create key with plan -> authenticate -> verify plan limits."""

from __future__ import annotations

import pytest
from httpx import ASGITransport, AsyncClient

from llmhosts.config import LLMHostsConfig, SecurityConfig
from llmhosts.proxy.app import create_app
from llmhosts.proxy.dispatcher import BackendDispatcher


@pytest.fixture
def configured_app():
    config = LLMHostsConfig()
    config.security = SecurityConfig(require_auth=True)
    return create_app(config)


@pytest.fixture
async def client(configured_app):
    dispatcher = BackendDispatcher()
    await dispatcher.startup()
    configured_app.state.dispatcher = dispatcher

    transport = ASGITransport(app=configured_app, raise_app_exceptions=False)
    async with AsyncClient(transport=transport, base_url="http://test") as c:
        yield c

    await dispatcher.shutdown()


@pytest.mark.asyncio
@pytest.mark.integration
async def test_full_flow_create_key_and_use(client: AsyncClient) -> None:
    # 1. Create a pro API key
    resp = await client.post("/api/keys", json={"label": "integration-test", "plan": "pro"})
    assert resp.status_code == 201
    raw_key = resp.json()["raw_key"]
    assert raw_key.startswith("lmh_")

    # 2. Use the key to list models
    resp = await client.get("/v1/models", headers={"Authorization": f"Bearer {raw_key}"})
    assert resp.status_code == 200
    assert resp.headers.get("x-ratelimit-limit") == "300"  # pro plan

    # 3. List keys (should see our key)
    resp = await client.get("/api/keys")
    keys = resp.json()["keys"]
    assert any(k["label"] == "integration-test" and k["plan"] == "pro" for k in keys)

    # 4. Revoke the key
    key_id = next(k["id"] for k in keys if k["label"] == "integration-test")
    resp = await client.delete(f"/api/keys/{key_id}")
    assert resp.status_code == 200

    # 5. Key should no longer work
    resp = await client.get("/v1/models", headers={"Authorization": f"Bearer {raw_key}"})
    assert resp.status_code == 401


@pytest.mark.asyncio
@pytest.mark.integration
async def test_anonymous_rejected_when_auth_required(client: AsyncClient) -> None:
    resp = await client.get("/v1/models")
    assert resp.status_code == 401


@pytest.mark.asyncio
@pytest.mark.integration
async def test_health_always_works(client: AsyncClient) -> None:
    resp = await client.get("/health")
    assert resp.status_code == 200
