import json
import logging
import time
from typing import Any, Optional

logger = logging.getLogger("app")

SCHEMA_VERSION = 1


def _normalize_value(value: Any) -> Any:
    if value is None:
        return None
    if isinstance(value, (str, int, float, bool)):
        return value
    return str(value)


def emit_question_metric(
    *,
    stage: str,
    status: str,
    duration_ms: Optional[int] = None,
    first_response_time_ms: Optional[int] = None,
    trace_id: Optional[str] = None,
    ai_id: Optional[str] = None,
    session_id: Optional[str] = None,
    robot_type: Optional[str] = None,
    model: Optional[str] = None,
    stream: Optional[bool] = None,
    error_type: Optional[str] = None,
    extra: Optional[dict[str, Any]] = None,
) -> None:
    payload: dict[str, Any] = {
        "schema_version": SCHEMA_VERSION,
        "event": {
            "kind": "metric",
            "category": ["question"],
            "action": "question_perf",
        },
        "stage": stage,
        "status": status,
        "observed_at": int(time.time() * 1000),
        "service": "catalog-agent",
    }

    optional_fields = {
        "trace_id": trace_id,
        "duration_ms": duration_ms,
        "first_response_time_ms": first_response_time_ms,
        "ai_id": ai_id,
        "session_id": session_id,
        "robot_type": robot_type,
        "model": model,
        "stream": stream,
        "error_type": error_type,
    }
    for key, value in optional_fields.items():
        normalized = _normalize_value(value)
        if normalized is not None:
            payload[key] = normalized

    if extra:
        for key, value in extra.items():
            normalized = _normalize_value(value)
            if normalized is not None:
                payload[key] = normalized

    logger.info(json.dumps(payload, ensure_ascii=False, separators=(",", ":")))
