"""Comando compile para build8bp."""

import os
import sys
import subprocess
import re
import shutil
from pathlib import Path
import click
from rich.console import Console
from rich.table import Table
from ..utils import get_asm_path, get_abasm_path, RichCommand

console = Console()


class CompileCommand(RichCommand):
    """Comando compile con ejemplos."""
    examples = [
        "build8bp compile --build 0",
        "build8bp compile --build 1 --asm-path ./8BP_V43/ASM",
        "export BP8_ASM_PATH=./8BP_V43/ASM && export ABASM_PATH=./abasm/src/abasm.py",
        "build8bp compile --build 2"
    ]

@click.command(cls=CompileCommand)
@click.option(
    "--build",
    type=click.IntRange(0, 4),
    required=True,
    help="Nivel de compilación: 0=completo, 1=laberintos, 2=scroll, 3=3D, 4=sin scroll/layout [requerido]",
)
@click.option(
    "--asm-path",
    type=click.Path(exists=True),
    help="Ruta a los scripts ASM (o usa $BP8_ASM_PATH)",
)
@click.option(
    "--abasm-path",
    type=click.Path(exists=True),
    help="Ruta a abasm.py (o usa $ABASM_PATH)",
)
def compile(build, asm_path, abasm_path):
    """
    Compilar proyecto 8BP con nivel de build especificado.
    Este comando permite compilar un proyecto 8BP con diferentes niveles de compilación.
    """
    console.print("[bold yellow]Iniciando compilación...[/bold yellow]")
    console.print(f"[bold blue]Nivel de compilación:[/bold blue] {build}")
    if asm_path:
        console.print(f"[bold blue]Ruta ASM:[/bold blue] {asm_path}")
    if abasm_path:
        console.print(f"[bold blue]Ruta ABASM:[/bold blue] {abasm_path}")
    
    asm_dir = get_asm_path(asm_path)
    abasm_py = get_abasm_path(abasm_path)
    
    if not asm_dir.exists():
        console.print(f"[red]Error: No existe el directorio {asm_dir}[/red]")
        sys.exit(1)
    
    if not abasm_py.exists():
        console.print(f"[red]Error: No existe {abasm_py}[/red]")
        sys.exit(1)
    
    # Descripción de cada build
    build_info = {
        0: ("Todas las funcionalidades", "MEMORY 23600", "|LAYOUT, |COLAY, |MAP2SP, |UMA, |3D"),
        1: ("Juegos de laberintos", "MEMORY 25000", "|LAYOUT, |COLAY"),
        2: ("Juegos con scroll", "MEMORY 24800", "|MAP2SP, |UMA"),
        3: ("Juegos pseudo-3D", "MEMORY 24000", "|3D"),
        4: ("Sin scroll/layout (+500 bytes)", "MEMORY 25500", "Básicos")
    }
    
    desc, memory, commands = build_info[build]
    
    console.print("\n[bold blue]═══════════════════════════════════════[/bold blue]")
    console.print(f"[bold blue]  BUILD8BP - Build {build}[/bold blue]")
    console.print("[bold blue]═══════════════════════════════════════[/bold blue]\n")
    
    table = Table(show_header=False, box=None)
    table.add_column("Key", style="cyan")
    table.add_column("Value", style="green")
    table.add_row("Descripción", desc)
    table.add_row("Memoria BASIC", memory)
    table.add_row("Comandos", commands)
    table.add_row("Directorio ASM", str(asm_dir))
    table.add_row("ABASM", str(abasm_py))
    console.print(table)
    console.print()
    
    # Modificar ASSEMBLING_OPTION
    make_file = asm_dir / "make_all_mygame.asm"
    if not make_file.exists():
        console.print(f"[red]Error: No existe {make_file}[/red]")
        sys.exit(1)
    
    console.print(f"[yellow]Configurando ASSEMBLING_OPTION = {build}...[/yellow]")
    
    content = make_file.read_text()
    content = re.sub(
        r'let ASSEMBLING_OPTION = \d',
        f'let ASSEMBLING_OPTION = {build}',
        content
    )
    make_file.write_text(content)
    
    # Crear carpeta dist
    dist_dir = asm_dir / "dist"
    dist_dir.mkdir(exist_ok=True)
    console.print(f"[cyan]Carpeta de salida:[/cyan] {dist_dir}")
    
    # Compilar con ABASM
    console.print("[yellow]Compilando con ABASM...[/yellow]")
    
    # Usar el mismo intérprete de Python que está ejecutando este script (multiplataforma)
    cmd = [
        sys.executable,
        str(abasm_py),
        str(make_file),
        "-o",
        str(asm_dir / "make_all_mygame.bin"),
        "--tolerance",
        "2"
    ]
    
    try:
        result = subprocess.run(
            cmd,
            cwd=asm_dir,
            capture_output=True,
            text=True,
            check=True
        )
        
        # Buscar el binario generado en el directorio ASM
        bin_file = asm_dir / f"8BP{build}.bin"
        if bin_file.exists():
            # Mover a dist
            dist_bin = dist_dir / bin_file.name
            shutil.move(str(bin_file), str(dist_bin))
            
            # Mover también otros archivos generados
            for ext in ['.lst', '.map', '.bin']:
                for generated_file in asm_dir.glob(f"*{ext}"):
                    if generated_file.name != f"8BP{build}.bin":  # Ya movido
                        dist_file = dist_dir / generated_file.name
                        shutil.move(str(generated_file), str(dist_file))
            
            size = dist_bin.stat().st_size
            console.print(f"\n[bold green]✓ Compilación exitosa![/bold green]")
            console.print(f"[green]  Archivo: {dist_bin.name}[/green]")
            console.print(f"[green]  Ubicación: {dist_bin}[/green]")
            console.print(f"[green]  Tamaño: {size:,} bytes[/green]")
            
            console.print("\n[cyan]Uso desde BASIC:[/cyan]")
            console.print(f"  {memory}")
            console.print(f'  LOAD"{bin_file.name}"')
            console.print("  CALL &6B78\n")
        else:
            console.print(f"[yellow]Advertencia: No se encontró el binario 8BP{build}.bin[/yellow]")
            
    except subprocess.CalledProcessError as e:
        console.print(f"\n[red]✗ Error en la compilación[/red]")
        if e.stderr:
            console.print("\n[yellow]Detalles del error:[/yellow]")
            # Mostrar solo las primeras líneas relevantes del error
            error_lines = e.stderr.strip().split('\n')
            for line in error_lines[:20]:  # Limitar a 20 líneas
                if line.strip():
                    console.print(f"  {line}")
        
        console.print("\n[cyan]Sugerencia:[/cyan]")
        console.print("  Si ves errores de sintaxis (and a,, djnz,, ifnot), ejecuta primero:")
        console.print(f"  [bold]build8bp patch --asm-path \"{asm_dir}\"[/bold]")
        sys.exit(1)
