"""
Status Bar - Display system information and metrics

Provides a status bar component that shows:
- Current model
- Token count (last message and total)
- Cost tracking
- Context window usage percentage
- MCP server status
- Current agent/mode

Examples:
    # Create status bar
    status = StatusBar()

    # Update metrics
    status.update_tokens(prompt=150, completion=300)
    status.update_cost(0.0045)
    status.set_model("gpt-4o")

    # Render
    formatted = status.render()
    print(formatted)  # Shows formatted status bar
"""

from dataclasses import dataclass, field
from typing import Optional
from enum import Enum


class ConnectionStatus(Enum):
    """Connection status indicators"""
    CONNECTED = "✓"
    DISCONNECTED = "✗"
    ERROR = "⚠"
    PENDING = "◌"


@dataclass
class TokenMetrics:
    """Token usage metrics"""
    prompt_tokens: int = 0
    completion_tokens: int = 0
    total_tokens: int = 0
    context_limit: int = 128000  # Default to 128k

    @property
    def context_percentage(self) -> float:
        """Calculate context window usage percentage"""
        if self.context_limit == 0:
            return 0.0
        return (self.total_tokens / self.context_limit) * 100

    @property
    def is_approaching_limit(self) -> bool:
        """Check if approaching context limit (>80%)"""
        return self.context_percentage > 80.0

    @property
    def is_near_limit(self) -> bool:
        """Check if near context limit (>95%)"""
        return self.context_percentage > 95.0


@dataclass
class CostMetrics:
    """Cost tracking metrics"""
    input_cost: float = 0.0
    output_cost: float = 0.0
    total_cost: float = 0.0

    def format_cost(self) -> str:
        """Format cost as currency string"""
        if self.total_cost == 0:
            return "$0.00"
        elif self.total_cost < 0.01:
            return f"${self.total_cost:.4f}"
        else:
            return f"${self.total_cost:.2f}"


@dataclass
class MCPServerStatus:
    """MCP server connection status"""
    name: str
    status: ConnectionStatus = ConnectionStatus.DISCONNECTED
    tool_count: int = 0


class StatusBar:
    """
    Status bar component for TUI

    Displays system metrics, model info, and connection status.

    Example:
        status = StatusBar()
        status.set_model("claude-3-5-sonnet")
        status.update_tokens(prompt=100, completion=200)
        status.update_cost(0.003)

        print(status.render())  # Shows formatted status bar
        print(status.render_compact())  # Shows minimal version
    """

    def __init__(self):
        """Initialize status bar"""
        self.model: str = "unknown"
        self.agent: str = "build"
        self.token_metrics = TokenMetrics()
        self.cost_metrics = CostMetrics()
        self.mcp_servers: list[MCPServerStatus] = []
        self.show_tokens: bool = True
        self.show_cost: bool = True
        self.show_mcp: bool = True
        self.show_agent: bool = True

    def set_model(self, model: str, context_limit: Optional[int] = None):
        """
        Set current model

        Args:
            model: Model name
            context_limit: Optional context window size
        """
        self.model = model
        if context_limit:
            self.token_metrics.context_limit = context_limit

    def set_agent(self, agent: str):
        """
        Set current agent

        Args:
            agent: Agent name (build, plan, oracle, etc.)
        """
        self.agent = agent

    def update_tokens(
        self,
        prompt: int = 0,
        completion: int = 0,
        total: Optional[int] = None
    ):
        """
        Update token metrics

        Args:
            prompt: Prompt tokens
            completion: Completion tokens
            total: Optional total (calculated if not provided)
        """
        self.token_metrics.prompt_tokens = prompt
        self.token_metrics.completion_tokens = completion
        self.token_metrics.total_tokens = total if total is not None else prompt + completion

    def update_cost(self, cost: float, input_cost: float = 0.0, output_cost: float = 0.0):
        """
        Update cost metrics

        Args:
            cost: Total cost
            input_cost: Optional input cost
            output_cost: Optional output cost
        """
        self.cost_metrics.total_cost = cost
        self.cost_metrics.input_cost = input_cost
        self.cost_metrics.output_cost = output_cost

    def add_mcp_server(self, name: str, status: ConnectionStatus, tool_count: int = 0):
        """
        Add or update MCP server status

        Args:
            name: Server name
            status: Connection status
            tool_count: Number of tools available
        """
        # Update existing or add new
        for server in self.mcp_servers:
            if server.name == name:
                server.status = status
                server.tool_count = tool_count
                return

        self.mcp_servers.append(MCPServerStatus(
            name=name,
            status=status,
            tool_count=tool_count
        ))

    def remove_mcp_server(self, name: str):
        """Remove MCP server from status"""
        self.mcp_servers = [s for s in self.mcp_servers if s.name != name]

    def render(self, width: Optional[int] = None) -> str:
        """
        Render full status bar

        Args:
            width: Optional terminal width for formatting

        Returns:
            Formatted status bar string
        """
        parts = []

        # Agent
        if self.show_agent:
            agent_icons = {
                "build": "🛠️",
                "plan": "📋",
                "oracle": "🔮",
                "explore": "🔍",
                "test": "🧪",
            }
            icon = agent_icons.get(self.agent, "🤖")
            parts.append(f"{icon} {self.agent.title()}")

        # Model
        parts.append(f"Model: {self.model}")

        # Tokens
        if self.show_tokens:
            tokens = self.token_metrics
            percentage = tokens.context_percentage

            # Color indicator
            if tokens.is_near_limit:
                indicator = "🔴"
            elif tokens.is_approaching_limit:
                indicator = "🟡"
            else:
                indicator = "🟢"

            token_str = f"{indicator} {tokens.total_tokens:,} tokens ({percentage:.1f}%)"
            parts.append(token_str)

        # Cost
        if self.show_cost and self.cost_metrics.total_cost > 0:
            cost_str = f"💰 {self.cost_metrics.format_cost()}"
            parts.append(cost_str)

        # MCP Servers
        if self.show_mcp and self.mcp_servers:
            connected = sum(1 for s in self.mcp_servers if s.status == ConnectionStatus.CONNECTED)
            total = len(self.mcp_servers)
            mcp_str = f"MCP: {connected}/{total}"
            parts.append(mcp_str)

        # Join with separator
        return " │ ".join(parts)

    def render_compact(self) -> str:
        """
        Render compact status bar (minimal info)

        Returns:
            Compact status string
        """
        parts = []

        # Agent icon only
        agent_icons = {
            "build": "🛠️",
            "plan": "📋",
            "oracle": "🔮",
            "explore": "🔍",
            "test": "🧪",
        }
        parts.append(agent_icons.get(self.agent, "🤖"))

        # Model abbreviation
        model_abbrev = {
            "gpt-4o": "4o",
            "gpt-4o-mini": "4o-mini",
            "claude-3-5-sonnet": "c3.5",
            "claude-3-opus": "c3-opus",
            "gemini-2.0-flash": "g2.0",
            "llama-3.3-70b-versatile": "ll3.3",
        }
        parts.append(model_abbrev.get(self.model, self.model[:10]))

        # Token percentage with indicator
        tokens = self.token_metrics
        if tokens.is_near_limit:
            indicator = "🔴"
        elif tokens.is_approaching_limit:
            indicator = "🟡"
        else:
            indicator = "🟢"
        parts.append(f"{indicator}{tokens.context_percentage:.0f}%")

        # Cost if non-zero
        if self.cost_metrics.total_cost > 0:
            parts.append(self.cost_metrics.format_cost())

        return " ".join(parts)

    def render_tokens_detail(self) -> str:
        """Render detailed token breakdown"""
        tokens = self.token_metrics
        lines = [
            "Token Usage:",
            f"  Prompt:     {tokens.prompt_tokens:,}",
            f"  Completion: {tokens.completion_tokens:,}",
            f"  Total:      {tokens.total_tokens:,}",
            f"  Limit:      {tokens.context_limit:,}",
            f"  Usage:      {tokens.context_percentage:.2f}%",
        ]
        return "\n".join(lines)

    def render_cost_detail(self) -> str:
        """Render detailed cost breakdown"""
        cost = self.cost_metrics
        lines = [
            "Cost Breakdown:",
            f"  Input:  {cost.input_cost:.4f}",
            f"  Output: {cost.output_cost:.4f}",
            f"  Total:  {cost.format_cost()}",
        ]
        return "\n".join(lines)

    def render_mcp_detail(self) -> str:
        """Render detailed MCP server status"""
        if not self.mcp_servers:
            return "MCP Servers: None configured"

        lines = ["MCP Servers:"]
        for server in self.mcp_servers:
            status_icon = server.status.value
            tool_info = f"({server.tool_count} tools)" if server.tool_count > 0 else ""
            lines.append(f"  {status_icon} {server.name} {tool_info}")
        return "\n".join(lines)

    def get_metrics_summary(self) -> dict:
        """
        Get all metrics as a dictionary

        Returns:
            Dictionary with all status metrics
        """
        return {
            "model": self.model,
            "agent": self.agent,
            "tokens": {
                "prompt": self.token_metrics.prompt_tokens,
                "completion": self.token_metrics.completion_tokens,
                "total": self.token_metrics.total_tokens,
                "limit": self.token_metrics.context_limit,
                "percentage": self.token_metrics.context_percentage,
            },
            "cost": {
                "input": self.cost_metrics.input_cost,
                "output": self.cost_metrics.output_cost,
                "total": self.cost_metrics.total_cost,
            },
            "mcp_servers": [
                {
                    "name": s.name,
                    "status": s.status.name,
                    "tools": s.tool_count,
                }
                for s in self.mcp_servers
            ],
        }


# Convenience functions

def create_status_bar() -> StatusBar:
    """Create a status bar with default configuration"""
    return StatusBar()


def format_tokens(prompt: int, completion: int, total: int, limit: int = 128000) -> str:
    """
    Format token count display

    Args:
        prompt: Prompt tokens
        completion: Completion tokens
        total: Total tokens
        limit: Context limit

    Returns:
        Formatted string
    """
    percentage = (total / limit * 100) if limit > 0 else 0

    if percentage > 95:
        indicator = "🔴"
    elif percentage > 80:
        indicator = "🟡"
    else:
        indicator = "🟢"

    return f"{indicator} {total:,} tokens ({percentage:.1f}%)"


def format_cost(cost: float) -> str:
    """
    Format cost as currency

    Args:
        cost: Cost value

    Returns:
        Formatted currency string
    """
    if cost == 0:
        return "$0.00"
    elif cost < 0.01:
        return f"${cost:.4f}"
    else:
        return f"${cost:.2f}"
