"""Prometheus metrics endpoint for monitoring."""

from __future__ import annotations

from starlette.requests import Request
from starlette.responses import Response

from bindu.server.applications import BinduApplication
from bindu.server.metrics import get_metrics
from bindu.utils.logging import get_logger

logger = get_logger("bindu.server.endpoints.metrics")


async def _update_agent_metrics(app: BinduApplication) -> None:
    """Update agent task metrics from the application state.

    Args:
        app: BinduApplication instance
    """
    if not app.task_manager or not app._storage:
        return

    metrics = get_metrics()

    # Get agent ID from manifest
    if app.manifest and app.manifest.did_extension:
        agent_id = app.manifest.did_extension.did

        try:
            # Count active tasks from storage (optimized)
            # We count tasks that are NOT in terminal states
            # Since count_tasks supports single status filtering, we might need multiple calls
            # or just count total active if storage supports it.
            # For now, let's use the most common active state "submitted" + "working"
            # Or if storage supports efficient filtering.

            # Optimization: most tasks are likely completed.
            # If we want total active, we can count total and subtract completed/failed?
            # Or just count 'submitted' and 'working' which are the main active ones.

            submitted = await app._storage.count_tasks(status="submitted")
            working = await app._storage.count_tasks(status="working")
            input_required = await app._storage.count_tasks(status="input-required")

            active_count = submitted + working + input_required
            metrics.set_agent_tasks_active(agent_id, active_count)

            # Count completed tasks by status
            # Note: This counts from current session only, not historical totals
            # For historical totals, you'd need to track this separately
        except Exception as e:
            logger.debug(f"Failed to update agent metrics: {e}")


async def metrics_endpoint(app: BinduApplication, request: Request) -> Response:
    """Prometheus metrics endpoint.

    Returns metrics in Prometheus text format for scraping.

    Metrics exposed:
    - http_requests_total: Total number of HTTP requests by method, endpoint, and status
    - http_request_duration_seconds: HTTP request latency histogram
    - agent_tasks_active: Currently active tasks per agent
    - agent_tasks_completed_total: Total completed tasks per agent and status
    """
    logger.debug("Metrics endpoint called")

    # Update agent metrics from current state
    await _update_agent_metrics(app)

    # Get metrics instance and generate Prometheus text
    metrics = get_metrics()
    prometheus_text = metrics.generate_prometheus_text()

    return Response(
        content=prometheus_text,
        media_type="text/plain; version=0.0.4; charset=utf-8",
        headers={
            "Cache-Control": "no-cache, no-store, must-revalidate",
            "Pragma": "no-cache",
            "Expires": "0",
        },
    )
