import asyncio
import random
from contextlib import asynccontextmanager

import uvicorn
from fastapi import FastAPI
from fast_telemetry.core import PrometheusMetrics
from fast_telemetry.integrations.fastapi import setup_fastapi_metrics
from starlette import status

service_name = "demo_service"
env = "production"
version = "1.0.0"

metrics = PrometheusMetrics(service_name=service_name, env=env, version=version)


@metrics.measure_task("heavy_calculation", long_task=True)
async def heavy_task():
    await asyncio.sleep(random.uniform(1, 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(_: FastAPI):
    asyncio.create_task(traffic_generator())
    yield


app = FastAPI(title=service_name, lifespan=lifespan, version=version)

setup_fastapi_metrics(app, metrics)


class PaymentError(Exception):
    pass


class DatabaseError(Exception):
    pass


@app.post("/foo")
async def foo(message: dict) -> None:
    print(f"Incoming message: {message}")


@app.get("/health", status_code=status.HTTP_204_NO_CONTENT)
async def health() -> None:
    return None


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