"""
STARWASTE - Client Main
Game client entry point with Arcade
"""

# Suppress Pyglet FFmpeg warning (we don't use audio/video)
import warnings
warnings.filterwarnings("ignore", message="FFmpeg release version not found")

import arcade
from arcade import gl
import asyncio
import argparse
import os
from dotenv import load_dotenv

from client.game_view import GameView
from client.network import NetworkClient
from shared.constants import SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, DEFAULT_PORT, VERSION
from shared.utils import console

load_dotenv()


class StarwasteGame(arcade.Window):
    """Main game window"""
    
    def __init__(self, host: str, port: int, username: str, start_server: bool = False):
        """
        Initialize game window
        
        Args:
            host: Server host
            port: Server port  
            username: Player username
            start_server: Start local server (singleplayer mode)
        """
        super().__init__(
            SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE, 
            resizable=True, 
            antialiasing=False,
            vsync=False  # 🔥 FPS FIX: Disable VSync - it was causing 30 FPS drops when frames took >16ms
        )
        
        # Set global pixelated rendering for all SpriteLists (pixel art style)
        arcade.SpriteList.DEFAULT_TEXTURE_FILTER = gl.NEAREST, gl.NEAREST
        
        self.host = host
        self.port = port
        self.username = username
        self.start_server = start_server
        
        self.network = NetworkClient()
        self.server_process = None
        
        console.print(f"🎮 STARWASTE Client v{VERSION}")
        console.print(f"   Player: {username}")
    
    def setup(self):
        """Setup game"""
        # Start local server if singleplayer
        if self.start_server:
            console.print("🖥️  Starting local server...")
            import subprocess
            import sys
            # Run server as module (python -m server.main)
            self.server_process = subprocess.Popen(
                [sys.executable, "-m", "server.main"],
                cwd=os.path.join(os.path.dirname(__file__), ".."),
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL
            )
            console.print("⏳ Server starting (client will retry connection async)...")
            # ❌ REMOVED: time.sleep(2) - blocking main thread!
            # ✅ Client will retry connection async with exponential backoff
        
        # Connect to server (will be done in game view)
        game_view = GameView(self.network)
        game_view.setup()
        self.show_view(game_view)
        
        # Start async connection in thread
        import threading
        def connect():
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            loop.run_until_complete(self._connect_to_server())
            loop.close()
        
        thread = threading.Thread(target=connect, daemon=True)
        thread.start()
    
    async def _connect_to_server(self):
        """Connect to server with exponential backoff retry"""
        max_retries = 10 if self.start_server else 3
        retry_delay = 0.5  # Start with 500ms
        
        for attempt in range(max_retries):
            try:
                if attempt > 0:
                    console.print(f"🔌 Retry {attempt}/{max_retries} - Connecting to {self.host}:{self.port}...")
                else:
                    console.print(f"🔌 Connecting to {self.host}:{self.port}...")
                
                connected = await self.network.connect(self.host, self.port, self.username)
                
                if connected:
                    console.print("✅ Connected to server!")
                    # Start network receive loop
                    await self.network.receive_loop()
                    return
                else:
                    console.print(f"❌ Connection failed (attempt {attempt + 1}/{max_retries})")
                    
            except (ConnectionRefusedError, OSError) as e:
                if attempt < max_retries - 1:
                    console.print(f"⏳ Server not ready, retrying in {retry_delay:.1f}s...")
                    await asyncio.sleep(retry_delay)
                    retry_delay = min(retry_delay * 2, 4.0)  # Exponential backoff, max 4s
                else:
                    console.print(f"❌ Failed to connect after {max_retries} attempts")
            except Exception as e:
                console.print(f"❌ Connection error: {e}")
                break
    
    def on_close(self):
        """Handle window close"""
        console.print("🛑 Shutting down...")
        
        # Stop local server if running
        if self.server_process:
            console.print("🛑 Stopping local server...")
            self.server_process.terminate()
            self.server_process.wait()
        
        super().on_close()


def main():
    """Main entry point"""
    parser = argparse.ArgumentParser(description="STARWASTE Client")
    parser.add_argument("--host", default="localhost", help="Server host")
    parser.add_argument("--port", type=int, default=DEFAULT_PORT, help="Server port")
    parser.add_argument("--username", default=os.getenv("USER", "Player"), help="Player username")
    parser.add_argument("--connect", help="Connect to server (format: host:port)")
    parser.add_argument("--multiplayer", action="store_true", 
                       help="Multiplayer mode (requires --connect)")
    
    args = parser.parse_args()
    
    # Parse connect argument
    if args.connect:
        parts = args.connect.split(":")
        args.host = parts[0]
        if len(parts) > 1:
            args.port = int(parts[1])
    
    # Determine mode
    start_server = not args.multiplayer and not args.connect
    
    if start_server:
        console.print("🎮 Starting in SINGLEPLAYER mode (local server)")
    else:
        console.print(f"🌐 Starting in MULTIPLAYER mode (connecting to {args.host}:{args.port})")
    
    # Create game
    game = StarwasteGame(
        host=args.host,
        port=args.port,
        username=args.username,
        start_server=start_server
    )
    
    game.setup()
    
    # Run with asyncio event loop
    arcade.run()


if __name__ == "__main__":
    main()
