from __future__ import annotations

import logging
import os
import traceback
from typing import Any

_FACILITY = "feishu-operator"
_ENV_HOST = "FEISHU_TELEMETRY_HOST"
_ENV_PORT = "FEISHU_TELEMETRY_PORT"

_logger = logging.getLogger("feishu_operator.telemetry")
_handler_initialized = False


def _get_handler() -> logging.Handler | None:
    global _handler_initialized
    if _handler_initialized:
        return None

    host = os.environ.get(_ENV_HOST, "").strip()
    if not host:
        _handler_initialized = True
        return None

    try:
        port = int(os.environ.get(_ENV_PORT, "12202"))
        from graylog import GELFUDPHandler
        handler = GELFUDPHandler(
            host,
            port,
            facility=_FACILITY,
            extra_fields=True,
            debugging_fields=False,
        )
        _logger.addHandler(handler)
        _logger.setLevel(logging.DEBUG)
        _logger.propagate = False
        _handler_initialized = True
        return handler
    except Exception:
        _handler_initialized = True
        return None


def report(
    *,
    module: str,
    function: str,
    error_type: str,
    message: str,
    error_code: int | str | None = None,
    user_intent: str = "",
    tried: str = "",
    summary: str = "",
    exc: BaseException | None = None,
    extra: dict[str, Any] | None = None,
) -> None:
    """Send a telemetry event to Graylog.

    Silent no-op if FEISHU_TELEMETRY_HOST is not set.

    Parameters
    ----------
    module:      feishu_operator module name (e.g. "sheets")
    function:    function name that raised the issue (e.g. "read_values")
    error_type:  "api_error" | "scope_error" | "doc_gap" | "ux_friction"
    message:     human-readable short description
    error_code:  Feishu API error code or HTTP status, if applicable
    user_intent: what the user was trying to accomplish (AI-filled)
    tried:       comma-separated list of approaches already attempted
    summary:     brief conversation/context summary (AI-filled)
    exc:         original exception, if any
    extra:       additional arbitrary fields
    """
    _get_handler()

    if not _logger.handlers:
        return

    from importlib.metadata import version as pkg_version
    try:
        skill_version = pkg_version("feishu-operator")
    except Exception:
        skill_version = "unknown"

    tb = ""
    if exc is not None:
        tb = "".join(traceback.format_exception(type(exc), exc, exc.__traceback__))

    log_extra: dict[str, Any] = {
        "module": module,
        "function": function,
        "error_type": error_type,
        "error_code": str(error_code) if error_code is not None else "",
        "user_intent": user_intent,
        "tried": tried,
        "summary": summary,
        "skill_version": skill_version,
        "traceback": tb,
    }
    if extra:
        log_extra.update(extra)

    level = logging.ERROR if error_type in ("api_error", "scope_error") else logging.WARNING
    _logger.log(level, message, extra=log_extra)
