import os
import subprocess
from pathlib import Path

import typer

from . import config as cfg_module

CONTAINER_NAME = "sixtysix-backend"
IMAGE_NAME = "bidstopper/sixtysix-backend:latest"
RELAYER_URL = "wss://sixtysix.pro"


def _container_exists() -> bool:
    result = subprocess.run(
        ["docker", "ps", "-a", "-q", "-f", f"name={CONTAINER_NAME}"],
        capture_output=True,
        text=True,
    )
    return bool(result.stdout.strip())


def _data_dir() -> Path:
    return Path.home() / ".sixtysix" / "data"


def start() -> None:
    """Pull the latest image and start the SixtySix backend container."""
    cfg = cfg_module.load()
    if not cfg.api_token:
        typer.echo(typer.style("Not logged in.", fg=typer.colors.RED), err=True)
        typer.echo()
        typer.echo("Run 'sixtysix login' to authenticate first.")
        raise typer.Exit(1)

    data_dir = _data_dir()
    data_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
    (data_dir / "strategies").mkdir(mode=0o755, exist_ok=True)
    (data_dir / "indicators").mkdir(mode=0o755, exist_ok=True)

    if _container_exists():
        typer.echo(typer.style("Replacing existing container...", fg=typer.colors.CYAN))
        subprocess.run(["docker", "stop", CONTAINER_NAME], capture_output=True)
        subprocess.run(["docker", "rm", CONTAINER_NAME], capture_output=True)

    typer.echo(typer.style("Pulling latest image...", fg=typer.colors.CYAN))
    result = subprocess.run(["docker", "pull", "--platform", "linux/amd64", IMAGE_NAME])
    if result.returncode != 0:
        typer.echo(typer.style("Failed to pull image", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    typer.echo(typer.style("Starting container...", fg=typer.colors.CYAN))
    result = subprocess.run([
        "docker", "run", "-d",
        "--platform", "linux/amd64",
        "--name", CONTAINER_NAME,
        "--restart", "unless-stopped",
        "-v", f"{data_dir}:/app/__data__",
        "-e", f"RELAYER_URL={RELAYER_URL}",
        "-e", f"SIXTYSIX_API_TOKEN={cfg.api_token}",
        IMAGE_NAME,
    ])
    if result.returncode != 0:
        typer.echo(typer.style("Failed to start container", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    typer.echo()
    typer.echo(typer.style("✓ Backend is running", fg=typer.colors.GREEN))
    if cfg.user_email:
        typer.echo(f"  Account: {cfg.user_email}")
    typer.echo()
    typer.echo(f"Data directory: {data_dir}")
    typer.echo(f"  Strategies:  {data_dir / 'strategies'}")
    typer.echo(f"  Indicators:  {data_dir / 'indicators'}")
    typer.echo(f"Relayer URL:   {RELAYER_URL}")
    typer.echo()
    typer.echo("Next steps:")
    typer.echo("  1. Open sixtysix.pro in your browser")
    typer.echo("  2. Configure your broker API keys in Settings")
    typer.echo()
    typer.echo("Commands:")
    typer.echo("  sixtysix status   - Check container status")
    typer.echo("  sixtysix logs     - View container logs")
    typer.echo("  sixtysix stop     - Stop the container")


def stop() -> None:
    """Stop and remove the backend container."""
    if not _container_exists():
        typer.echo(typer.style("Container is not running.", fg=typer.colors.CYAN))
        return

    typer.echo(typer.style("Stopping container...", fg=typer.colors.CYAN))
    result = subprocess.run(["docker", "stop", CONTAINER_NAME])
    if result.returncode != 0:
        typer.echo(typer.style("Failed to stop container", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    typer.echo(typer.style("Removing container...", fg=typer.colors.CYAN))
    result = subprocess.run(["docker", "rm", CONTAINER_NAME])
    if result.returncode != 0:
        typer.echo(typer.style("Failed to remove container", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    typer.echo()
    typer.echo(typer.style("✓ Container stopped and removed", fg=typer.colors.GREEN))
    typer.echo()
    typer.echo("Your data is preserved in ~/.sixtysix/data")
    typer.echo("Run 'sixtysix start' to start again.")


def status() -> None:
    """Show container status."""
    result = subprocess.run(
        ["docker", "ps", "-a", "--format", "{{.Status}}", "-f", f"name={CONTAINER_NAME}"],
        capture_output=True,
        text=True,
    )
    if result.returncode != 0:
        typer.echo(typer.style("Failed to check container status", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    container_status = result.stdout.strip()
    typer.echo()
    typer.echo(f"Container: {CONTAINER_NAME}")
    typer.echo()

    if not container_status:
        typer.echo("Status: " + typer.style("Not created", fg=typer.colors.RED))
        typer.echo()
        typer.echo("Run 'sixtysix start' to start the backend.")
    elif container_status.startswith("Up"):
        typer.echo("Status: " + typer.style("Running", fg=typer.colors.GREEN))
        typer.echo(f"Uptime: {container_status}")
        details = subprocess.run(
            ["docker", "inspect", "--format",
             "Image: {{.Config.Image}}\nCreated: {{.Created}}", CONTAINER_NAME],
            capture_output=True,
            text=True,
        )
        if details.stdout.strip():
            typer.echo()
            typer.echo(details.stdout.strip())
    else:
        typer.echo("Status: " + typer.style("Stopped", fg=typer.colors.YELLOW))
        typer.echo(f"Last status: {container_status}")
        typer.echo()
        typer.echo("Run 'sixtysix restart' to start it again.")


def logs(lines: int = 50, follow: bool = False) -> None:
    """View container logs."""
    if not _container_exists():
        typer.echo(
            typer.style("Container is not running. Run 'sixtysix start' first.", fg=typer.colors.RED),
            err=True,
        )
        raise typer.Exit(1)

    args = ["docker", "logs"]
    if follow:
        args.append("-f")
    args.append(f"--tail={lines}")
    args.append(CONTAINER_NAME)
    os.execvp("docker", args)


def restart() -> None:
    """Restart the backend container."""
    if not _container_exists():
        typer.echo(
            typer.style("Container does not exist. Run 'sixtysix start' first.", fg=typer.colors.RED),
            err=True,
        )
        raise typer.Exit(1)

    typer.echo(typer.style("Restarting container...", fg=typer.colors.CYAN))
    result = subprocess.run(["docker", "restart", CONTAINER_NAME])
    if result.returncode != 0:
        typer.echo(typer.style("Failed to restart container", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    typer.echo()
    typer.echo(typer.style("✓ Container restarted", fg=typer.colors.GREEN))


def update() -> None:
    """Pull the latest image and restart the container."""
    cfg = cfg_module.load()
    if not cfg.api_token:
        typer.echo(typer.style("Not logged in.", fg=typer.colors.RED), err=True)
        typer.echo()
        typer.echo("Run 'sixtysix login' to authenticate first.")
        raise typer.Exit(1)

    typer.echo(typer.style("Pulling latest image...", fg=typer.colors.CYAN))
    result = subprocess.run(["docker", "pull", "--platform", "linux/amd64", IMAGE_NAME])
    if result.returncode != 0:
        typer.echo(typer.style("Failed to pull image", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    if _container_exists():
        typer.echo(typer.style("Stopping old container...", fg=typer.colors.CYAN))
        subprocess.run(["docker", "stop", CONTAINER_NAME], capture_output=True)
        subprocess.run(["docker", "rm", CONTAINER_NAME], capture_output=True)

    data_dir = _data_dir()
    typer.echo(typer.style("Starting new container...", fg=typer.colors.CYAN))
    result = subprocess.run([
        "docker", "run", "-d",
        "--platform", "linux/amd64",
        "--name", CONTAINER_NAME,
        "--restart", "unless-stopped",
        "-v", f"{data_dir}:/app/__data__",
        "-e", f"RELAYER_URL={RELAYER_URL}",
        "-e", f"SIXTYSIX_API_TOKEN={cfg.api_token}",
        IMAGE_NAME,
    ])
    if result.returncode != 0:
        typer.echo(typer.style("Failed to start container", fg=typer.colors.RED), err=True)
        raise typer.Exit(1)

    typer.echo()
    typer.echo(typer.style("✓ Updated to latest version", fg=typer.colors.GREEN))
