#!/usr/bin/env python3
"""
Development environment management script for the Crypto Trading Bot Dashboard.
"""

import subprocess
import sys
import time
import os
from pathlib import Path


def run_command(command: str, check: bool = True) -> subprocess.CompletedProcess:
    """Run a shell command and return the result."""
    print(f"Running: {command}")
    return subprocess.run(command, shell=True, check=check)


def check_docker():
    """Check if Docker is installed and running."""
    try:
        result = subprocess.run(
            "docker --version", shell=True, capture_output=True, text=True
        )
        if result.returncode != 0:
            print("❌ Docker is not installed or not in PATH")
            return False
            
        result = subprocess.run(
            "docker info", shell=True, capture_output=True, text=True
        )
        if result.returncode != 0:
            print("❌ Docker daemon is not running")
            return False
            
        print("✅ Docker is available and running")
        return True
    except Exception as e:
        print(f"❌ Error checking Docker: {e}")
        return False


def start_services():
    """Start all development services."""
    print("🚀 Starting development environment...")
    
    if not check_docker():
        sys.exit(1)
    
    # Start Docker services
    run_command("docker-compose up -d")
    
    # Wait for services to be ready
    print("⏳ Waiting for services to be ready...")
    time.sleep(10)
    
    # Check service health
    check_services()


def stop_services():
    """Stop all development services."""
    print("🛑 Stopping development environment...")
    run_command("docker-compose down")


def restart_services():
    """Restart all development services."""
    print("🔄 Restarting development environment...")
    stop_services()
    start_services()


def check_services():
    """Check the status of all services."""
    print("🔍 Checking service status...")
    
    # Check Docker containers
    result = subprocess.run(
        "docker-compose ps", shell=True, capture_output=True, text=True
    )
    print(result.stdout)
    
    # Check database connection
    check_database()


def check_database():
    """Check if the database is accessible."""
    try:
        import psycopg2
        from dotenv import load_dotenv
        
        # Load environment variables
        env_file = Path(".env")
        if env_file.exists():
            load_dotenv(env_file)
        
        conn_params = {
            "host": os.getenv("POSTGRES_HOST", "localhost"),
            "port": os.getenv("POSTGRES_PORT", "5432"),
            "database": os.getenv("POSTGRES_DB", "dashboard"),
            "user": os.getenv("POSTGRES_USER", "dashboard"),
            "password": os.getenv("POSTGRES_PASSWORD", "dashboard123"),
        }
        
        conn = psycopg2.connect(**conn_params)
        conn.close()
        print("✅ Database connection successful")
        
    except ImportError:
        print("⚠️  psycopg2 not installed, skipping database check")
    except Exception as e:
        print(f"❌ Database connection failed: {e}")


def setup_env():
    """Set up environment files."""
    print("📝 Setting up environment...")
    
    env_file = Path(".env")
    template_file = Path("env.template")
    
    if not env_file.exists() and template_file.exists():
        import shutil
        shutil.copy(template_file, env_file)
        print(f"✅ Created .env file from template")
        print(f"⚠️  Please update .env with your actual configuration")
    elif env_file.exists():
        print("✅ .env file already exists")
    else:
        print("❌ No env.template file found")


def install_deps():
    """Install project dependencies using UV."""
    print("📦 Installing dependencies...")
    run_command("uv sync --dev")


def run_dev_server():
    """Run the development server with hot reload."""
    print("🔥 Starting development server with hot reload...")
    
    try:
        from watchdog.observers import Observer
        from watchdog.events import FileSystemEventHandler
        import threading
        import signal
        
        class ChangeHandler(FileSystemEventHandler):
            def __init__(self, restart_callback):
                self.restart_callback = restart_callback
                self.last_modified = 0
                
            def on_modified(self, event):
                if event.is_directory:
                    return
                    
                # Only watch Python files
                if not event.src_path.endswith('.py'):
                    return
                    
                # Avoid rapid restarts
                current_time = time.time()
                if current_time - self.last_modified < 1:
                    return
                    
                self.last_modified = current_time
                print(f"\n📝 File changed: {event.src_path}")
                self.restart_callback()
        
        # Application process
        app_process = None
        
        def start_app():
            nonlocal app_process
            if app_process:
                app_process.terminate()
                app_process.wait()
            
            print("🚀 Starting application...")
            app_process = subprocess.Popen([
                sys.executable, "main.py"
            ])
            
        def restart_app():
            print("🔄 Restarting application...")
            start_app()
            
        # Set up file watcher
        event_handler = ChangeHandler(restart_app)
        observer = Observer()
        
        # Watch main directories
        watch_dirs = [".", "config", "database", "components", "data", "strategies", "trader"]
        for watch_dir in watch_dirs:
            if Path(watch_dir).exists():
                observer.schedule(event_handler, watch_dir, recursive=True)
                print(f"👀 Watching: {watch_dir}/")
        
        # Start watching
        observer.start()
        
        # Start initial app
        start_app()
        
        def signal_handler(signum, frame):
            print("\n🛑 Shutting down development server...")
            observer.stop()
            if app_process:
                app_process.terminate()
                app_process.wait()
            sys.exit(0)
            
        signal.signal(signal.SIGINT, signal_handler)
        
        print("🔥 Development server running with hot reload")
        print("📁 Watching for changes in Python files...")
        print("Press Ctrl+C to stop")
        
        # Keep the main thread alive
        observer.join()
        
    except ImportError:
        print("❌ watchdog not installed, running without hot reload")
        print("Install with: uv add watchdog")
        # Fallback to regular execution
        run_command("uv run python main.py")
    except KeyboardInterrupt:
        print("\n🛑 Development server stopped")
    except Exception as e:
        print(f"❌ Error running dev server: {e}")


def run_app():
    """Run the application without hot reload."""
    print("🚀 Starting application...")
    run_command("uv run python main.py")


def main():
    """Main entry point for the development script."""
    if len(sys.argv) < 2:
        print("Usage: python scripts/dev.py [command]")
        print("Commands:")
        print("  setup       - Set up environment and install dependencies")
        print("  start       - Start development services (Docker)")
        print("  stop        - Stop development services")
        print("  restart     - Restart development services")
        print("  status      - Check service status")
        print("  install     - Install dependencies")
        print("  dev-server  - Run development server with hot reload")
        print("  run         - Run application without hot reload")
        sys.exit(1)
    
    command = sys.argv[1]
    
    if command == "setup":
        setup_env()
        install_deps()
    elif command == "start":
        start_services()
    elif command == "stop":
        stop_services()
    elif command == "restart":
        restart_services()
    elif command == "status":
        check_services()
    elif command == "install":
        install_deps()
    elif command == "dev-server":
        run_dev_server()
    elif command == "run":
        run_app()
    else:
        print(f"Unknown command: {command}")
        sys.exit(1)


if __name__ == "__main__":
    main() 