"""
Status Dashboard - Visual status display for the orchestrator.

This module provides formatted status views for:
- Agent status and availability
- Task queue status
- Usage statistics
- System health
"""

from datetime import datetime
from typing import Any, Dict, List, Optional

from ..tracking.cli_usage import AgentAvailability


class StatusDashboard:
    """
    Generates formatted status displays for the orchestrator.
    """

    # Status emojis
    AVAILABILITY_EMOJI = {
        "available": "🟢",
        "busy": "🟡",
        "limited": "🟠",
        "rate_limited": "🔶",
        "exhausted": "🔴",
        "unavailable": "⚫",
        "paused": "⏸️",
    }

    HEALTH_EMOJI = {
        True: "✓",
        False: "✗",
    }

    @classmethod
    def format_agent_status(
        cls,
        agents: List[Dict[str, Any]],
        show_usage: bool = True,
    ) -> str:
        """
        Format agent status for display.

        Args:
            agents: List of agent status dictionaries
            show_usage: Whether to show usage percentages

        Returns:
            Formatted string
        """
        if not agents:
            return "No agents registered."

        lines = ["AGENT STATUS", "-" * 60]

        for agent in agents:
            emoji = cls.AVAILABILITY_EMOJI.get(agent.get("availability", ""), "⚪")
            agent_id = agent.get("id", "unknown")
            status = agent.get("availability", "unknown")

            line = f"{emoji} {agent_id:<18} [{status:<12}]"

            if show_usage:
                usage = agent.get("session_percentage", 0)
                bar = cls._progress_bar(usage, width=15)
                line += f"  {bar} {usage:>3.0f}%"

            lines.append(line)

        return "\n".join(lines)

    @classmethod
    def format_task_queue(
        cls,
        tasks: List[Dict[str, Any]],
        max_display: int = 10,
    ) -> str:
        """
        Format task queue for display.

        Args:
            tasks: List of task dictionaries
            max_display: Maximum tasks to display

        Returns:
            Formatted string
        """
        if not tasks:
            return "No pending tasks."

        lines = ["TASK QUEUE", "-" * 60]

        for task in tasks[:max_display]:
            task_id = task.get("id", "?")[:12]
            description = task.get("description", "")[:40]
            status = task.get("status", "?")
            assigned = task.get("assigned_to", "unassigned")

            status_marker = {
                "pending": "○",
                "in_progress": "●",
                "completed": "✓",
                "failed": "✗",
            }.get(status, "?")

            lines.append(f"{status_marker} [{task_id}] {description}...")
            lines.append(f"    → {assigned} ({status})")

        if len(tasks) > max_display:
            lines.append(f"  ... and {len(tasks) - max_display} more tasks")

        return "\n".join(lines)

    @classmethod
    def format_usage_stats(
        cls,
        usage_stats: Dict[str, Dict[str, Any]],
    ) -> str:
        """
        Format usage statistics for display.

        Args:
            usage_stats: Dictionary of agent_id -> usage dict

        Returns:
            Formatted string
        """
        if not usage_stats:
            return "No usage data available."

        lines = [
            "USAGE STATISTICS",
            "-" * 60,
            f"{'Agent':<18} {'Requests':<10} {'Tokens':<12} {'Errors':<8} {'Session':<10}",
            "-" * 60,
        ]

        for agent_id, stats in usage_stats.items():
            requests = stats.get("total_requests", 0)
            tokens = stats.get("total_tokens", 0)
            errors = stats.get("error_count", 0)
            session = stats.get("session_percentage", 0)

            # Format tokens with K/M suffix
            if tokens >= 1_000_000:
                tokens_str = f"{tokens / 1_000_000:.1f}M"
            elif tokens >= 1_000:
                tokens_str = f"{tokens / 1_000:.1f}K"
            else:
                tokens_str = str(tokens)

            lines.append(
                f"{agent_id:<18} {requests:<10} {tokens_str:<12} {errors:<8} {session:>6.0f}%"
            )

        return "\n".join(lines)

    @classmethod
    def format_health_check(
        cls,
        health_data: Dict[str, Dict[str, Any]],
        warnings: List[str],
    ) -> str:
        """
        Format health check results for display.

        Args:
            health_data: Dictionary of agent_id -> health dict
            warnings: List of warning messages

        Returns:
            Formatted string
        """
        lines = ["HEALTH CHECK", "-" * 60]

        overall_healthy = True
        for agent_id, health in health_data.items():
            is_healthy = health.get("healthy", False)
            overall_healthy = overall_healthy and is_healthy

            emoji = cls.HEALTH_EMOJI[is_healthy]
            availability = health.get("availability", "unknown")
            error_rate = health.get("error_rate", 0) * 100

            lines.append(
                f"{emoji} {agent_id:<18} {availability:<12} "
                f"Error rate: {error_rate:.1f}%"
            )

        lines.append("-" * 60)
        lines.append(f"Overall: {'HEALTHY' if overall_healthy else 'UNHEALTHY'}")

        if warnings:
            lines.append("")
            lines.append("WARNINGS:")
            for warning in warnings:
                lines.append(f"  ⚠️  {warning}")

        return "\n".join(lines)

    @classmethod
    def format_system_report(
        cls,
        report: Dict[str, Any],
    ) -> str:
        """
        Format a full system report for display.

        Args:
            report: Report data from brain.commands._cmd_report

        Returns:
            Formatted string
        """
        lines = [
            "=" * 60,
            "SYSTEM REPORT",
            f"Generated: {report.get('generated_at', 'unknown')}",
            "=" * 60,
            "",
        ]

        # Project info
        project = report.get("project", {})
        lines.extend([
            "PROJECT",
            f"  Name: {project.get('name', 'Unknown')}",
            f"  Phase: {project.get('phase', 'Unknown')}",
            f"  Version: {project.get('version', '0.0.0')}",
            "",
        ])

        # Agents
        agents = report.get("agents", {})
        lines.extend([
            f"AGENTS ({agents.get('total', 0)} registered)",
        ])

        for agent in agents.get("details", []):
            emoji = cls.AVAILABILITY_EMOJI.get(agent.get("availability", ""), "⚪")
            lines.append(
                f"  {emoji} {agent.get('id', '?'):<15} "
                f"[{agent.get('availability', '?'):<10}] "
                f"{agent.get('usage_pct', 0):.0f}% used, "
                f"{agent.get('requests', 0)} requests, "
                f"{agent.get('errors', 0)} errors"
            )

        # Tasks
        tasks = report.get("tasks", {})
        lines.extend([
            "",
            "TASKS",
            f"  Pending: {tasks.get('pending', 0)}",
            f"  In Progress: {tasks.get('in_progress', 0)}",
            "",
            f"Recent Decisions: {report.get('recent_decisions', 0)}",
            "",
            "=" * 60,
        ])

        return "\n".join(lines)

    @classmethod
    def format_workload_analysis(
        cls,
        analysis: Dict[str, Any],
    ) -> str:
        """
        Format workload analysis for display.

        Args:
            analysis: Analysis data from brain.analyze_workload

        Returns:
            Formatted string
        """
        lines = [
            "WORKLOAD ANALYSIS",
            f"Timestamp: {analysis.get('timestamp', 'unknown')}",
            "-" * 60,
        ]

        workload = analysis.get("workload", {})
        lines.extend([
            f"Pending Tasks: {workload.get('pending_tasks', 0)}",
            f"In Progress: {workload.get('in_progress_tasks', 0)}",
            f"Active Agents: {workload.get('active_agents', 0)}",
            "",
        ])

        recommendations = analysis.get("recommendations", [])
        if recommendations:
            lines.append("RECOMMENDATIONS:")
            for rec in recommendations:
                rec_type = rec.get("type", "?")
                message = rec.get("message", "")
                lines.append(f"  [{rec_type.upper()}] {message}")

                # Show additional details
                if "task_ids" in rec:
                    for tid in rec["task_ids"][:3]:
                        lines.append(f"    - {tid}")
                if "agent_id" in rec:
                    lines.append(f"    Agent: {rec['agent_id']}")
        else:
            lines.append("No recommendations - system is operating normally.")

        warnings = analysis.get("warnings", [])
        if warnings:
            lines.extend(["", "WARNINGS:"])
            for warning in warnings:
                lines.append(f"  ⚠️  {warning}")

        return "\n".join(lines)

    @staticmethod
    def _progress_bar(percentage: float, width: int = 20) -> str:
        """Generate a text-based progress bar."""
        filled = int(width * percentage / 100)
        empty = width - filled

        # Use different characters based on fill level
        if percentage >= 90:
            fill_char = "█"
        elif percentage >= 70:
            fill_char = "▓"
        elif percentage >= 50:
            fill_char = "▒"
        else:
            fill_char = "░"

        return f"[{fill_char * filled}{'·' * empty}]"


def print_dashboard(
    brain: Any,
    view: str = "status",
) -> None:
    """
    Print a dashboard view to the console.

    Args:
        brain: OrchestrationBrain instance
        view: View type (status, tasks, usage, health, report)
    """
    status = brain.get_system_status()

    if view == "status":
        print(StatusDashboard.format_agent_status(
            status["agents"]["registered"]
        ))
    elif view == "tasks":
        pending = brain.db.get_pending_tasks(limit=20)
        tasks = [
            {
                "id": t.id,
                "description": t.description,
                "status": t.status,
                "assigned_to": t.assigned_to,
            }
            for t in pending
        ]
        print(StatusDashboard.format_task_queue(tasks))
    elif view == "usage":
        usage_data = {}
        for agent_id in brain._adapters:
            usage_data[agent_id] = brain.cli_tracker.get_usage_stats(agent_id)
        print(StatusDashboard.format_usage_stats(usage_data))
    elif view == "health":
        health_data = {}
        for agent_id in brain._adapters:
            avail = brain.cli_tracker.get_availability(agent_id)
            usage = brain.cli_tracker.get_usage_stats(agent_id)
            health_data[agent_id] = {
                "healthy": avail not in (
                    AgentAvailability.EXHAUSTED,
                    AgentAvailability.UNAVAILABLE
                ),
                "availability": avail.value,
                "error_rate": usage.get("error_rate", 0),
            }
        print(StatusDashboard.format_health_check(
            health_data,
            status["warnings"]
        ))
    elif view == "report":
        import asyncio
        result = asyncio.get_event_loop().run_until_complete(
            brain.commands.execute("/report")
        )
        if result.success:
            print(StatusDashboard.format_system_report(result.data))
