"""Shared utilities for CLI commands."""

import time
from typing import Any, Dict

from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.table import Table

from flow import Flow, TaskStatus

console = Console()


def display_config(config: Dict[str, Any]) -> None:
    """Display task configuration in a formatted table."""
    table = Table(title="Task Configuration", show_header=False)
    table.add_column("Property", style="cyan")
    table.add_column("Value")

    # Extract key configuration values
    if "name" in config:
        table.add_row("Name", config.get("name"))

    command = config.get("command", "N/A")
    if isinstance(command, list):
        command = " ".join(command)
    table.add_row("Command", command)
    table.add_row("Instance Type", config.get("instance_type", "N/A"))

    if "resources" in config:
        resources = config["resources"]
        table.add_row("vCPUs", str(resources.get("vcpus", "N/A")))
        table.add_row("Memory", f"{resources.get('memory', 'N/A')} GB")
        table.add_row("GPUs", str(resources.get("gpus", 0)))

    if "storage" in config:
        table.add_row("Storage", f"{config['storage']} GB")

    if "mounts" in config and config["mounts"]:
        mount_strs = []
        for mount in config["mounts"]:
            if isinstance(mount, dict):
                source = mount.get("source", "")
                target = mount.get("target", "")
                mount_strs.append(f"{target} → {source}")
        if mount_strs:
            table.add_row("Mounts", "\n".join(mount_strs))

    console.print(table)


def wait_for_task(flow_client: Flow, task_id: str, watch: bool = False, json_output: bool = False) -> TaskStatus:
    """Wait for a task to reach running state with progress indication."""
    if json_output:
        # For JSON output, just poll without visual progress
        while True:
            status = flow_client.status(task_id)
            if status.state not in ["pending", "preparing"]:
                return status
            time.sleep(2)

    if watch:
        # Interactive watching mode
        with Progress(
            SpinnerColumn(),
            TextColumn("[progress.description]{task.description}"),
            console=console,
            transient=True,
        ) as progress:
            task = progress.add_task("Waiting for task to start...", total=None)

            while True:
                status = flow_client.status(task_id)

                if status.state == "pending":
                    progress.update(task, description="[yellow]Pending:[/yellow] Waiting for resources...")
                elif status.state == "preparing":
                    progress.update(task, description="[blue]Preparing:[/blue] Setting up instance...")
                elif status.state == "running":
                    progress.update(task, description="[green]Running:[/green] Task is now active")
                    break
                elif status.state in ["completed", "failed", "cancelled"]:
                    break

                time.sleep(2)

        return status
    else:
        # Simple waiting mode
        console.print(f"Task submitted with ID: [cyan]{task_id}[/cyan]")
        console.print("Waiting for task to start...")

        dots = 0
        while True:
            status = flow_client.status(task_id)

            if status.state not in ["pending", "preparing"]:
                console.print()  # New line after dots
                return status

            # Show progress dots
            console.print(".", end="", markup=False)
            dots += 1
            if dots % 50 == 0:
                console.print()  # New line every 50 dots

            time.sleep(2)


def get_status_style(status: str) -> str:
    """Get the color style for a task status."""
    status_colors = {
        "pending": "yellow",
        "preparing": "blue",
        "running": "green",
        "completed": "green",
        "failed": "red",
        "cancelled": "red",
        "unknown": "dim",
    }
    return status_colors.get(status.lower(), "white")
