"""OpenTelemetry metrics and traces panel.

Displays request metrics, per-backend breakdown, and recent trace
waterfall when OTel integration is enabled.
"""

from __future__ import annotations

import logging
from typing import Any, Dict, List

from textual.app import ComposeResult
from textual.containers import Vertical
from textual.widget import Widget
from textual.widgets import DataTable, Label, Static

logger = logging.getLogger(__name__)


class OTelPanel(Widget):
    """OpenTelemetry metrics and trace display widget."""

    DEFAULT_CSS = """
    OTelPanel {
        height: auto;
        max-height: 24;
        border: round $accent;
        padding: 0 1;
    }
    #otel-title {
        text-style: bold;
        color: $primary;
        margin-bottom: 0;
    }
    #otel-status {
        height: 1;
        color: $text-muted;
    }
    #otel-metrics {
        height: auto;
        max-height: 4;
        padding: 0 1;
        margin: 1 0;
    }
    #otel-backend-table {
        height: auto;
        max-height: 8;
    }
    #otel-trace {
        height: auto;
        max-height: 6;
        padding: 0 1;
        margin-top: 1;
    }
    """

    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self._enabled: bool = False

    def compose(self) -> ComposeResult:
        with Vertical():
            yield Label("[b]Telemetry[/b] — OpenTelemetry Integration", id="otel-title")
            yield Static("OTel: [dim]● inactive[/dim]", id="otel-status")

            yield Static("[b]Request Metrics[/b]")
            yield Static(
                "  Total requests: —     Errors: —\n"
                "  Avg latency: —        P99: —\n"
                "  Active sessions: —",
                id="otel-metrics",
            )

            yield Static("[b]Per-Backend Breakdown[/b]")
            yield DataTable(id="otel-backend-table")

            yield Static("[b]Last Trace[/b]")
            yield Static("(no traces captured)", id="otel-trace")

    def on_mount(self) -> None:
        try:
            table = self.query_one("#otel-backend-table", DataTable)
            table.add_columns("Backend", "Calls", "Avg ms", "Err%", "Health")
            table.cursor_type = "row"
            table.zebra_stripes = True
        except Exception:
            pass

    def update_otel_status(
        self,
        enabled: bool = False,
        exporter: str = "",
        prometheus_url: str = "",
    ) -> None:
        """Update OTel connection status."""
        self._enabled = enabled
        if enabled:
            status = f"OTel: [green]● active[/green]    Exporter: {exporter}"
            if prometheus_url:
                status += f"    Prometheus: {prometheus_url}"
        else:
            status = "OTel: [dim]● inactive[/dim]    (enable in config)"

        try:
            self.query_one("#otel-status", Static).update(status)
        except Exception:
            pass

    def update_metrics(
        self,
        total_requests: int = 0,
        errors: int = 0,
        avg_latency_ms: float = 0,
        p99_latency_ms: float = 0,
        active_sessions: int = 0,
    ) -> None:
        """Update aggregate request metrics."""
        err_pct = (errors / total_requests * 100) if total_requests > 0 else 0
        text = (
            f"  Total requests (1h): {total_requests:,}     Errors: {errors} ({err_pct:.1f}%)\n"
            f"  Avg latency: {avg_latency_ms:.0f}ms        P99: {p99_latency_ms:.0f}ms\n"
            f"  Active sessions: {active_sessions}"
        )
        try:
            self.query_one("#otel-metrics", Static).update(text)
        except Exception:
            pass

    def update_backend_breakdown(self, backends: List[Dict[str, Any]]) -> None:
        """Update the per-backend metrics table."""
        try:
            table = self.query_one("#otel-backend-table", DataTable)
            table.clear()
            for b in backends:
                name = b.get("name", "?")
                calls = b.get("calls", 0)
                avg_ms = b.get("avg_latency_ms", 0)
                err_pct = b.get("error_percent", 0)
                health = b.get("health", {})
                health_status = (
                    health.get("status", "unknown") if isinstance(health, dict) else str(health)
                )

                if health_status == "healthy":
                    health_display = "[green]●[/green]"
                elif health_status == "degraded":
                    health_display = "[yellow]◑[/yellow]"
                else:
                    health_display = "[red]✕[/red]"

                table.add_row(
                    name,
                    str(calls),
                    f"{avg_ms:.0f}",
                    f"{err_pct:.1f}%",
                    health_display,
                )
        except Exception:
            pass

    def update_trace(self, trace_info: Dict[str, Any]) -> None:
        """Display a trace waterfall for the last request."""
        try:
            tool = trace_info.get("tool", "—")
            spans = trace_info.get("spans", [])
            total_ms = trace_info.get("total_ms", 0)
            lines = [f"  {tool} — Total: {total_ms}ms"]
            for span in spans:
                name = span.get("name", "?")
                duration = span.get("duration_ms", 0)
                bar_len = max(1, int(duration / max(total_ms, 1) * 30))
                bar = "█" * bar_len + "░" * (30 - bar_len)
                lines.append(f"  ├── {name:<18} {bar}  {duration}ms")
            self.query_one("#otel-trace", Static).update("\n".join(lines))
        except Exception:
            pass
