import asyncio

import pytest

from libs.events.base import EventPayload
from libs.events.nats_bus import NATSEventBus
from libs.schemas.events import DocumentIngestedEventData


@pytest.mark.asyncio
async def test_nats_bus_class():
    """Test NATSEventBus class within pytest."""

    import time

    unique_suffix = int(time.time())
    stream_name = f"PYTEST_DEBUG_STREAM_{unique_suffix}"

    print(f"\nStarting NATSEventBus with stream {stream_name}...")
    bus = NATSEventBus(
        servers="nats://localhost:4222",
        stream_name=stream_name,
        consumer_group="test-debug-group",
    )

    await bus.start()
    print("Bus started.")

    # Clean up (just in case)
    try:
        await bus.js.delete_stream(stream_name)
    except Exception:
        pass
    await bus._ensure_stream_exists()

    # Wait for stream to be ready
    await asyncio.sleep(2)

    try:
        info = await bus.js.stream_info(stream_name)
        print(f"Stream info: {info.config.subjects}")
    except Exception as e:
        print(f"Failed to get stream info: {e}")

    # Setup subscriber
    received_event = asyncio.Future()

    async def handler(topic, event):
        print(f"Handler received event: {event.event_id}")
        if not received_event.done():
            received_event.set_result(event)

    await bus.subscribe("doc.ingested", handler)

    print("Publishing message...")

    data = DocumentIngestedEventData(
        doc_id="test-doc-123",
        filename="test.pdf",
        mime_type="application/pdf",
        size_bytes=1024,
        source="upload",
        kind="invoice",
        storage_path="s3://test-bucket/test.pdf",
        checksum_sha256="a" * 64,
    )

    payload = EventPayload(
        data=data.model_dump(mode="json"),
        actor="tester",
        tenant_id="tenant-1",
        schema_version="1.0",
    )
    payload.event_id = "evt-debug-1"

    success = await bus.publish("doc.ingested", payload)
    print(f"Published: {success}")

    try:
        result = await asyncio.wait_for(received_event, timeout=5.0)
        print(f"Received event: {result.event_id}")
        assert result.event_id == "evt-debug-1"
        assert result.data["doc_id"] == "test-doc-123"
    except TimeoutError:
        print("Timeout waiting for event")
        raise

    await bus.stop()
    print("Bus stopped.")

    # Cleanup stream
    try:
        nc = await nats.connect("nats://localhost:4222")
        js = nc.jetstream()
        await js.delete_stream(stream_name)
        await nc.close()
    except Exception:
        pass
