import argparse
import subprocess
import sys
import shutil
import os
import threading
from pathlib import Path

# Import existing scripts as modules
from django_core_micha.scripts import generate_env, sync_secrets

def run_command(command, cwd=None, ignore_errors=False, shell=False, capture_output=False):
    """Helper function to execute shell commands."""
    if not capture_output:
        print(f"[INFO] Running: {' '.join(command) if isinstance(command, list) else command}")
    
    try:
        is_windows = sys.platform == "win32"
        use_shell = shell or is_windows
        
        if capture_output:
            return subprocess.Popen(command, cwd=cwd, shell=use_shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        
        subprocess.run(command, check=True, cwd=cwd, shell=use_shell)
    except subprocess.CalledProcessError as e:
        if ignore_errors:
            print(f"[WARN] Command failed (ignored): {e}")
        else:
            print(f"[ERROR] Command failed: {e}")
            sys.exit(e.returncode)

def stream_docker_logs(compose_files_args):
    """
    Runs in a separate thread to stream docker logs while frontend is running.
    """
    print("[INFO] Starting Docker Log Stream...")
    # EDIT: java_backend entfernt, um Lärm zu reduzieren.
    # Nur noch Django (backend) und Celery sind wichtig für die Entwicklung.
    cmd = ["docker-compose"] + compose_files_args + ["logs", "-f", "--tail=10", "backend", "celery_worker"]
    
    try:
        subprocess.run(cmd, check=False, shell=(sys.platform == "win32"))
    except Exception as e:
        print(f"[WARN] Log stream interrupted: {e}")

def main():
    parser = argparse.ArgumentParser(description="Developer Runner for Docker setup")
    parser.add_argument("--local", action="store_true", help="Set environment to local")
    parser.add_argument("--edge", action="store_true", help="Set environment to edge")
    parser.add_argument("--all", action="store_true", help="Sync ALL secrets")
    
    parser.add_argument("--env", action="store_true", help="Force regenerate .env file")
    parser.add_argument("--vite", action="store_true", help="Use Hot-Reloading Mode (Vite on Host)")
    parser.add_argument("--docker", action="store_true", help="Use Classic Mode (Full Docker Build)")
    parser.add_argument("--refresh", action="store_true", help="Force refresh of Python dependencies")

    args = parser.parse_args()

    # --- KONFIGURATION ---
    BASE_DIR = Path(__file__).resolve().parent
    frontend_dir = BASE_DIR / "frontend"
    env_mode = "edge" if args.edge else "local"
    MODE = "VITE" if args.vite else "CLASSIC"
    FORCE_ENV = args.env

    if args.refresh:
        print("[INFO] 🐢 Dependency Refresh ACTIVE: Downloading latest packages...")
        os.environ["UV_FLAGS"] = "--refresh"
    else:
        os.environ["UV_FLAGS"] = ""

    print(f"==================================================")
    print(f"🚀 RUN-DEV | Mode: {MODE} | Env-Regen: {FORCE_ENV}")
    print(f"==================================================")

    # --- SCHRITT 1: ENV GENERATION ---
    if FORCE_ENV:
        if args.local or args.all:
            sys.argv = ["sync-secrets", "--target", "local"]
            sync_secrets.main()
        if args.all:
            sys.argv = ["sync-secrets", "--target", "github"]
            sync_secrets.main()

        print(f"[INFO] Generating .env for {env_mode}...")
        sys.argv = ["generate-env", "--env", env_mode]
        generate_env.main()

        frontend_env_path = frontend_dir / ".env"
        if frontend_dir.exists():
            shutil.copy(".env", frontend_env_path)
    else:
        print("[INFO] Skipping .env generation (use --env to force)")


    # --- SCHRITT 2: DOCKER FILES ---
    compose_files_args = ["-f", "docker-compose.yml"]
    if args.edge:
        if Path("docker-compose.edge.yml").exists():
            compose_files_args.extend(["-f", "docker-compose.edge.yml"])
    elif MODE == "VITE":
        if Path("docker-compose.local.yml").exists():
            compose_files_args.extend(["-f", "docker-compose.local.yml"])
        else:
            print("[ERROR] --vite requires docker-compose.local.yml!")
            sys.exit(1)
    elif MODE == "CLASSIC":
        if Path("docker-compose.override.yml").exists():
             compose_files_args.extend(["-f", "docker-compose.override.yml"])

    print(f"[INFO] Compose files: {' '.join(compose_files_args)}")

    # --- SCHRITT 3: CLEANUP ---
    print("[INFO] Stopping containers...")
    run_command(["docker", "rm", "-f", "traefik"], ignore_errors=True)
    # Stille Cleanup (stderr unterdrücken wenn Container nicht existieren)
    subprocess.run(["docker-compose"] + compose_files_args + ["rm", "-s", "-f", "-v", "backend", "celery_worker"], 
                   stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL, shell=(sys.platform=="win32"))


    # --- SCHRITT 4: START ---
    
    if MODE == "CLASSIC":
        print("[INFO] Starting Classic Docker Build...")
        run_command(["docker-compose"] + compose_files_args + ["build"])
        run_command(["docker-compose"] + compose_files_args + ["up", "--remove-orphans"])

    elif MODE == "VITE":
        # 1. Backend starten
        print("[INFO] Starting Backend Containers...")
        run_command(["docker-compose"] + compose_files_args + ["up", "-d", "--build", "--remove-orphans"])
        
        # 2. Frontend
        if frontend_dir.exists():
            print("\n[INFO] Starting Vite...")
            
            # Logs im Hintergrund
            log_thread = threading.Thread(target=stream_docker_logs, args=(compose_files_args,), daemon=True)
            log_thread.start()

            try:
                # EDIT: Install und Dev trennen für bessere Stabilität
                # 1. Install (Interaktiv möglich)
                print("[INFO] Running pnpm install...")
                subprocess.run("pnpm install", cwd=str(frontend_dir), shell=True, check=True)
                
                # 2. Dev (Interaktiv)
                print("[INFO] Running pnpm dev...")
                subprocess.run("pnpm dev", cwd=str(frontend_dir), shell=True, check=True)
                
            except KeyboardInterrupt:
                print("\n[INFO] Stopping...")
            except subprocess.CalledProcessError as e:
                print(f"[ERROR] Frontend process failed: {e}")
        else:
             print("[WARN] No frontend directory found!")
             run_command(["docker-compose"] + compose_files_args + ["logs", "-f"])

if __name__ == "__main__":
    main()