import asyncio
import os
import random
from contextlib import asynccontextmanager

import uvicorn
from faststream.asgi import make_ping_asgi, AsgiFastStream
from faststream.rabbit import RabbitBroker

from fast_telemetry.core import PrometheusMetrics
from fast_telemetry.integrations.faststream import setup_faststream_metrics

service_name = "foo_service"
env = "dev"
version = "1.2.3"
queue = "foo"
metrics = PrometheusMetrics(service_name=service_name, version=version, env=env)

url = (
    f"amqp://{os.getenv('RABBITMQ_DEFAULT_USER')}:{os.getenv('RABBITMQ_DEFAULT_PASS')}"
    f"@{os.getenv('RABBITMQ_DEFAULT_HOST')}:{os.getenv('RABBITMQ_DEFAULT_PORT')}/"
)
broker = RabbitBroker(url)


@metrics.measure_task("heavy_calculation")
async def heavy_task():
    await asyncio.sleep(random.uniform(0.1, 0.5))


@metrics.track_exception
async def risky_task():
    if random.random() < 0.3:
        raise PaymentError("Payment declined")
    if random.random() < 0.1:
        raise DatabaseError("Connection lost")
    await asyncio.sleep(0.05)


async def traffic_generator():
    print("🚀 Traffic generator started...")
    while True:
        try:
            await heavy_task()
            await risky_task()
        except Exception as ex:
            print(f"Error: {ex}")
        await asyncio.sleep(5)


@asynccontextmanager
async def lifespan():
    asyncio.create_task(traffic_generator())
    yield


app = AsgiFastStream(
    broker, asgi_routes=[("/health", make_ping_asgi(broker))], asyncapi_path="/docs", lifespan=lifespan
)


setup_faststream_metrics(app, metrics)


class PaymentError(Exception):
    pass


class DatabaseError(Exception):
    pass


@broker.subscriber(queue)
async def foo(msg: dict) -> dict:
    print("incoming message:", msg)
    await broker.publish({"some_number": random.randint(1, 100)}, "delete_me")
    return {"message": msg}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
