"""
AWOOOI Deep Linking - Phase 15.3
================================
三系統觀測互連: Sentry ↔ SignOz ↔ Langfuse

Phase 15.3 (2026-03-26)
實現零斷鏈觀測的最後一哩路

架構:
┌─────────┐     trace_id      ┌─────────┐     trace_id      ┌──────────┐
│ Sentry  │ ◄──────────────► │ SignOz  │ ◄──────────────► │ Langfuse │
│ Errors  │                   │ Traces  │                   │ LLMOps   │
└─────────┘                   └─────────┘                   └──────────┘

URL 格式:
- SignOz Trace: http://192.168.0.188:3301/trace/{trace_id}
- Langfuse Trace: http://192.168.0.110:3100/trace/{langfuse_trace_id}
- Sentry Issue: http://192.168.0.110:9000/organizations/sentry/issues/{issue_id}/

Usage:
    from src.core.deep_linking import DeepLinking

    # 取得 SignOz Trace URL
    url = DeepLinking.signoz_trace_url(trace_id)

    # 取得 Langfuse Trace URL
    url = DeepLinking.langfuse_trace_url(langfuse_trace_id)
"""

from src.core.config import settings


class DeepLinking:
    """
    三系統 Deep Linking URL 生成器

    統帥鐵律 (Phase 15.3):
    - 所有觀測系統必須能互相跳轉
    - URL 必須使用內網 IP (非 localhost)
    - 確保 trace_id 格式一致 (32 hex chars)
    """

    # ==========================================================================
    # SignOz URLs (Traces/Metrics/Logs)
    # ==========================================================================

    SIGNOZ_BASE_URL = "http://192.168.0.188:3301"

    @classmethod
    def signoz_trace_url(cls, trace_id: str) -> str:
        """
        生成 SignOz Trace 詳情頁 URL

        Args:
            trace_id: 32 字元 hex 格式 (e.g., "0af7651916cd43dd8448eb211c80319c")

        Returns:
            SignOz Trace URL (e.g., http://192.168.0.188:3301/trace/0af7651916cd43dd8448eb211c80319c)
        """
        if not trace_id:
            return ""
        # SignOz v3 URL 格式
        return f"{cls.SIGNOZ_BASE_URL}/trace/{trace_id}"

    @classmethod
    def signoz_service_url(cls, service_name: str = "awoooi-api") -> str:
        """
        生成 SignOz Service 監控頁 URL

        Args:
            service_name: 服務名稱

        Returns:
            SignOz Service URL
        """
        return f"{cls.SIGNOZ_BASE_URL}/services/{service_name}"

    @classmethod
    def signoz_logs_url(cls, trace_id: str | None = None) -> str:
        """
        生成 SignOz Logs 頁面 URL

        Args:
            trace_id: 可選，用於過濾特定 trace 的 logs

        Returns:
            SignOz Logs URL
        """
        if trace_id:
            # SignOz v3 logs 過濾語法
            return f"{cls.SIGNOZ_BASE_URL}/logs?q=trace_id%3D{trace_id}"
        return f"{cls.SIGNOZ_BASE_URL}/logs"

    # ==========================================================================
    # Langfuse URLs (LLMOps)
    # ==========================================================================

    LANGFUSE_BASE_URL = settings.LANGFUSE_URL or "http://192.168.0.110:3100"

    @classmethod
    def langfuse_trace_url(cls, trace_id: str, project: str = "awoooi-openclaw") -> str:
        """
        生成 Langfuse Trace 詳情頁 URL

        Args:
            trace_id: Langfuse trace ID
            project: Langfuse 專案名稱

        Returns:
            Langfuse Trace URL
        """
        if not trace_id:
            return ""
        return f"{cls.LANGFUSE_BASE_URL}/project/{project}/traces/{trace_id}"

    @classmethod
    def langfuse_dashboard_url(cls, project: str = "awoooi-openclaw") -> str:
        """
        生成 Langfuse Dashboard URL

        Args:
            project: Langfuse 專案名稱

        Returns:
            Langfuse Dashboard URL
        """
        return f"{cls.LANGFUSE_BASE_URL}/project/{project}"

    # ==========================================================================
    # Sentry URLs (Error Tracking)
    # ==========================================================================

    SENTRY_BASE_URL = "http://192.168.0.110:9000"
    SENTRY_ORG = "sentry"  # Self-hosted 預設組織

    @classmethod
    def sentry_issue_url(cls, issue_id: str) -> str:
        """
        生成 Sentry Issue 詳情頁 URL

        Args:
            issue_id: Sentry issue ID

        Returns:
            Sentry Issue URL
        """
        if not issue_id:
            return ""
        return f"{cls.SENTRY_BASE_URL}/organizations/{cls.SENTRY_ORG}/issues/{issue_id}/"

    @classmethod
    def sentry_project_url(cls, project_slug: str) -> str:
        """
        生成 Sentry Project 頁面 URL

        Args:
            project_slug: Sentry 專案 slug

        Returns:
            Sentry Project URL
        """
        return f"{cls.SENTRY_BASE_URL}/organizations/{cls.SENTRY_ORG}/projects/{project_slug}/"

    # ==========================================================================
    # Cross-System Deep Linking
    # ==========================================================================

    @classmethod
    def get_all_links(
        cls,
        otel_trace_id: str | None = None,
        langfuse_trace_id: str | None = None,
        sentry_issue_id: str | None = None,
    ) -> dict[str, str]:
        """
        取得所有可用的 Deep Links

        Args:
            otel_trace_id: OpenTelemetry trace ID (32 hex)
            langfuse_trace_id: Langfuse trace ID
            sentry_issue_id: Sentry issue ID

        Returns:
            dict with available deep links

        Example:
            {
                "signoz_trace": "http://...",
                "langfuse_trace": "http://...",
                "sentry_issue": "http://...",
            }
        """
        links = {}

        if otel_trace_id:
            links["signoz_trace"] = cls.signoz_trace_url(otel_trace_id)
            links["signoz_logs"] = cls.signoz_logs_url(otel_trace_id)

        if langfuse_trace_id:
            links["langfuse_trace"] = cls.langfuse_trace_url(langfuse_trace_id)

        if sentry_issue_id:
            links["sentry_issue"] = cls.sentry_issue_url(sentry_issue_id)

        return links

    @classmethod
    def format_for_log(
        cls,
        otel_trace_id: str | None = None,
        langfuse_trace_id: str | None = None,
    ) -> str:
        """
        格式化 Deep Links 供 log 輸出

        Returns:
            Formatted string for logging
        """
        parts = []

        if otel_trace_id:
            parts.append(f"SignOz: {cls.signoz_trace_url(otel_trace_id)}")

        if langfuse_trace_id:
            parts.append(f"Langfuse: {cls.langfuse_trace_url(langfuse_trace_id)}")

        return " | ".join(parts) if parts else "No trace links available"
