"""
Base class for all framework integrations.
"""
from abc import ABC, abstractmethod
from typing import List, Optional


class TraceSummary:
    """Summary of a completed trace, available after track() exits."""

    def __init__(
        self,
        name: str,
        status: str,
        llm_calls: int,
        tool_calls: int,
        total_tokens: int,
        total_cost: float,
        duration_s: float,
        agents: List[str],
        sent: bool,
    ):
        self.name = name
        self.status = status
        self.llm_calls = llm_calls
        self.tool_calls = tool_calls
        self.total_tokens = total_tokens
        self.total_cost = total_cost
        self.duration_s = duration_s
        self.agents = agents
        self.sent = sent

    def __str__(self):
        if self.total_cost < 0.01:
            cost_str = f"${self.total_cost:.6f}"
        else:
            cost_str = f"${self.total_cost:.4f}"
        parts = [
            f"Trace: {self.name}",
            f"{self.llm_calls} LLM calls",
            f"{self.total_tokens:,} tokens",
            cost_str,
            f"{self.duration_s:.1f}s",
        ]
        if self.tool_calls:
            parts.append(f"{self.tool_calls} tool calls")
        if self.agents:
            parts.append(f"agents: {', '.join(self.agents)}")
        parts.append(f"status: {self.status}")
        parts.append(f"sent: {'OK' if self.sent else 'FAILED'}")
        return " | ".join(parts)

    def __repr__(self):
        return f"TraceSummary(name={self.name!r}, status={self.status!r}, sent={self.sent})"


class BaseIntegration(ABC):
    """
    Abstract base class for framework integrations.

    All integrations should inherit from this and implement
    the required methods.
    """

    def __init__(self, client):
        """
        Initialize integration.

        Args:
            client: Visibe client instance
        """
        self.client = client

    @abstractmethod
    def track(self, *args, **kwargs):
        """
        Main tracking method.

        Each integration implements this differently based on
        the framework's architecture.
        """
        pass
