"""
Status Display - Real-time Grid status visualization.

"I fight for the Users."
"""

from typing import Optional, TYPE_CHECKING

if TYPE_CHECKING:
    from core.grid import Grid
    from core.cluster import Cluster
    from core.block import Block
    from core.thread import Thread
    from core.program import Program
    from core.energy import EnergyPool, EnergyLevel

# Import enums at runtime (they don't cause circular imports)
from core.thread import ThreadStatus
from core.energy import EnergyLevel


def render_cluster_status(cluster: "Cluster") -> str:
    """
    Render detailed Cluster status.

    Returns formatted string showing Cluster with all Blocks and Threads.
    """
    WIDTH = 75

    # Header with energy
    energy_display = ""
    if cluster.energy_pool:
        energy_display = f"Energy: {cluster.energy_pool.remaining}"

    # Calculate padding for header
    header_content = f"CLUSTER: {cluster.name}"
    padding = WIDTH - len(header_content) - len(energy_display) - 4

    lines = [
        "╔" + "═" * WIDTH + "╗",
        f"║  {header_content}{' ' * padding}{energy_display}  ║",
        "╠" + "═" * WIDTH + "╣",
        "║" + " " * WIDTH + "║",
    ]

    # Render each Block
    for block_id in cluster.block_order:
        block = cluster.blocks[block_id]
        block_lines = render_block(block, WIDTH - 4)
        for line in block_lines:
            # Pad line to exact width
            padded = line + " " * (WIDTH - 2 - len(line))
            lines.append(f"║ {padded} ║")
        lines.append("║" + " " * WIDTH + "║")

    # I/O Tower checkpoints
    for checkpoint in cluster.io_tower_checkpoints:
        content = f"⛯ I/O TOWER: {checkpoint}"
        padded = content + " " * (WIDTH - 2 - len(content))
        lines.append(f"║ {padded} ║")

    lines.append("║" + " " * WIDTH + "║")
    lines.append("╚" + "═" * WIDTH + "╝")

    return "\n".join(lines)


def render_block(block: "Block", width: int = 71) -> list[str]:
    """Render a Block with its Threads."""
    inner_width = width - 2  # Account for box chars

    header_text = f"─ BLOCK: {block.name} "
    header = "┌" + header_text + "─" * (inner_width - len(header_text)) + "┐"
    lines = [header]

    for thread_id in block.thread_order:
        thread = block.threads[thread_id]
        lines.append(render_thread_line(thread, inner_width))

    lines.append("└" + "─" * inner_width + "┘")
    return lines


def render_thread_line(thread: "Thread", width: int = 69) -> str:
    """Render a single Thread status line."""
    icon = thread.program_icon()
    ptype = "Recognizer" if thread.program_type == "recognizer" else "Program"

    if thread.status == ThreadStatus.BLOCKED:
        action = f"Blocked by: {', '.join(thread.blocked_by[:2])}"
        if len(thread.blocked_by) > 2:
            action += "..."
    else:
        action = thread.current_action

    # Truncate action if too long
    if len(action) > 25:
        action = action[:22] + "..."

    progress = f"{thread.status_icon()} {thread.progress:.0f}%"

    content = f" {icon} {thread.name:<14} {ptype:<10} {action:<25} {progress}"
    # Pad to width
    padded = content + " " * (width - len(content) - 1)
    return f"│{padded}│"


def render_energy_flow(grid: "Grid") -> str:
    """Render energy flow visualization."""
    lines = [
        "ENERGY FLOW",
        "═" * 40,
        grid.energy.grid_pool.summary(),
    ]

    # Show cluster pools
    for pool_id, pool in grid.energy.pools.items():
        if pool_id.startswith("cluster:"):
            lines.append(f"  └─ {pool.summary()}")

            # Show block pools under this cluster
            for block_id, block_pool in grid.energy.pools.items():
                if block_id.startswith("block:") and block_pool.parent == pool:
                    lines.append(f"       ├─ {block_pool.summary()}")

    return "\n".join(lines)


def render_program_tree(program: "Program", indent: int = 0) -> list[str]:
    """Render a Program and its children as a tree."""
    prefix = "  " * indent
    icon = program.status_icon()

    line = f"{prefix}{icon} {program.name}"
    if program.disc.energy_allocated > 0:
        energy_pct = program.energy_percentage()
        line += f" [{energy_pct:.0f}%]"
    line += f" - {program.current_action}"

    lines = [line]

    for child in program.children:
        lines.extend(render_program_tree(child, indent + 1))

    return lines


def render_grid_summary(grid: "Grid") -> str:
    """Render Grid summary status."""
    summary = grid.get_status_summary()

    lines = [
        "╔" + "═" * 50 + "╗",
        "║  THE GRID - Status Summary" + " " * 23 + "║",
        "╠" + "═" * 50 + "╣",
        f"║  Status:           {summary['status']:<29}║",
        f"║  Clusters:         {summary['clusters']:<29}║",
        f"║  Active Programs:  {summary['active_programs']:<29}║",
        f"║  Programs Spawned: {summary['programs_spawned']:<29}║",
        f"║  Programs Derezzed:{summary['programs_derezzed']:<29}║",
        f"║  Cycles Completed: {summary['cycles_completed']:<29}║",
        "╠" + "═" * 50 + "╣",
        f"║  Energy Remaining: {summary['energy_remaining']:,}  " + " " * 20 + "║",
        f"║  Energy Consumed:  {summary['energy_consumed']:,}" + " " * 20 + "║",
        "╚" + "═" * 50 + "╝",
    ]

    return "\n".join(lines)


def render_controls() -> str:
    """Render control key display."""
    return """
  [P] Pause   [R] Resume   [D] Disc (view context)   [E] Energy status   [Q] Quit
    """.strip()


def render_full_status(grid: "Grid") -> str:
    """Render full Grid status with all Clusters."""
    lines = [grid.render_status()]

    for cluster in grid.clusters.values():
        lines.append("")
        lines.append(render_cluster_status(cluster))

    lines.append("")
    lines.append(render_controls())

    return "\n".join(lines)


def get_status_icon(status: str) -> str:
    """Get icon for status string."""
    icons = {
        "pending": "○",
        "running": "◐",
        "blocked": "◌",
        "completed": "●",
        "failed": "✗",
        "derezzed": "◯",
        "initializing": "○",
        "spawning": "◎",
        "waiting": "◑",
    }
    return icons.get(status.lower(), "?")


def get_energy_level_color(level: EnergyLevel) -> str:
    """Get ANSI color for energy level."""
    colors = {
        EnergyLevel.FULL: "\033[92m",      # Green
        EnergyLevel.NORMAL: "\033[94m",    # Blue
        EnergyLevel.LOW: "\033[93m",       # Yellow
        EnergyLevel.CRITICAL: "\033[91m",  # Red
    }
    return colors.get(level, "")


def render_progress_bar(progress: float, width: int = 20, filled_char: str = "█", empty_char: str = "░") -> str:
    """Render a progress bar."""
    filled = int((progress / 100) * width)
    empty = width - filled
    return filled_char * filled + empty_char * empty
