#!/usr/bin/env python3
"""
Real-time Performance Monitor
Shows detailed timing breakdown of game loop
"""

import arcade
from arcade import shape_list
import time
from collections import deque

class PerformanceMonitor:
    """
    Real-time performance monitoring overlay
    Shows timing breakdown for on_draw and on_update
    """
    
    def __init__(self):
        self.frame_times = deque(maxlen=60)  # Last 60 frames
        self.draw_times = deque(maxlen=60)
        self.update_times = deque(maxlen=60)
        self.sprite_draw_times = deque(maxlen=60)
        self.ground_draw_times = deque(maxlen=60)
        self.texture_load_times = deque(maxlen=60)
        self.chunk_process_times = deque(maxlen=60)
        self.network_times = deque(maxlen=60)
        
        self.last_frame_time = time.perf_counter()
        self.current_draw_start = 0
        self.current_update_start = 0
        
        # Current timings
        self.fps = 60
        self.frame_ms = 16.7
        self.draw_ms = 0
        self.update_ms = 0
        self.sprite_draw_ms = 0
        self.ground_draw_ms = 0
        self.texture_load_ms = 0
        self.chunk_process_ms = 0
        self.network_ms = 0
        
        # Text objects (created once, updated each frame) - FAST!
        self.title_text = None
        self.fps_text = None
        self.frame_text = None
        self.draw_text = None
        self.update_text = None
        self.ground_text = None
        self.sprite_text = None
        self.texture_text = None
        self.chunk_text = None
        self.network_text = None
        self.budget_text = None
    
    def start_frame(self):
        """Call at start of frame"""
        current_time = time.perf_counter()
        frame_time = current_time - self.last_frame_time
        self.frame_times.append(frame_time)
        self.last_frame_time = current_time
        
        # Calculate FPS
        if len(self.frame_times) > 0:
            avg_frame_time = sum(self.frame_times) / len(self.frame_times)
            self.fps = 1.0 / avg_frame_time if avg_frame_time > 0 else 60
            self.frame_ms = avg_frame_time * 1000
    
    def start_draw(self):
        """Call at start of on_draw"""
        self.current_draw_start = time.perf_counter()
    
    def end_draw(self):
        """Call at end of on_draw"""
        draw_time = time.perf_counter() - self.current_draw_start
        self.draw_times.append(draw_time)
        self.draw_ms = (sum(self.draw_times) / len(self.draw_times)) * 1000
    
    def start_update(self):
        """Call at start of on_update"""
        self.current_update_start = time.perf_counter()
    
    def end_update(self):
        """Call at end of on_update"""
        update_time = time.perf_counter() - self.current_update_start
        self.update_times.append(update_time)
        self.update_ms = (sum(self.update_times) / len(self.update_times)) * 1000
    
    def record_sprite_draw(self, duration: float):
        """Record time spent drawing sprites"""
        self.sprite_draw_times.append(duration)
        self.sprite_draw_ms = (sum(self.sprite_draw_times) / len(self.sprite_draw_times)) * 1000
    
    def record_ground_draw(self, duration: float):
        """Record time spent drawing ground"""
        self.ground_draw_times.append(duration)
        self.ground_draw_ms = (sum(self.ground_draw_times) / len(self.ground_draw_times)) * 1000
    
    def record_texture_load(self, duration: float):
        """Record time spent loading textures"""
        self.texture_load_times.append(duration)
        self.texture_load_ms = (sum(self.texture_load_times) / len(self.texture_load_times)) * 1000
    
    def record_chunk_process(self, duration: float):
        """Record time spent processing chunks"""
        self.chunk_process_times.append(duration)
        self.chunk_process_ms = (sum(self.chunk_process_times) / len(self.chunk_process_times)) * 1000
    
    def record_network(self, duration: float):
        """Record time spent on network operations"""
        self.network_times.append(duration)
        self.network_ms = (sum(self.network_times) / len(self.network_times)) * 1000
    
    def draw(self, window_width: int, window_height: int):
        """Draw performance overlay using cached Text objects - FAST!"""
        # Background - create rectangle shape (larger for new metrics)
        x_left = window_width - 290
        x_right = window_width - 10
        y_top = window_height - 20
        y_bottom = window_height - 280
        
        bg_shape = shape_list.create_rectangle_filled(
            (x_left + x_right) / 2,
            (y_top + y_bottom) / 2,
            x_right - x_left,
            y_top - y_bottom,
            (0, 0, 0, 180)
        )
        bg_shape.draw()
        
        # Create Text objects on first draw
        if self.title_text is None:
            self.title_text = arcade.Text("⚡ PERFORMANCE", 0, 0, arcade.color.YELLOW, 12, bold=True)
            self.fps_text = arcade.Text("", 0, 0, arcade.color.GREEN, 11, bold=True)
            self.frame_text = arcade.Text("", 0, 0, arcade.color.WHITE, 10)
            self.draw_text = arcade.Text("", 0, 0, arcade.color.GREEN, 10)
            self.update_text = arcade.Text("", 0, 0, arcade.color.GREEN, 10)
            self.ground_text = arcade.Text("", 0, 0, arcade.color.LIGHT_GRAY, 9)
            self.sprite_text = arcade.Text("", 0, 0, arcade.color.LIGHT_GRAY, 9)
            self.texture_text = arcade.Text("", 0, 0, arcade.color.ORANGE, 9)
            self.chunk_text = arcade.Text("", 0, 0, arcade.color.CYAN, 9)
            self.network_text = arcade.Text("", 0, 0, arcade.color.LIGHT_BLUE, 9)
            self.budget_text = arcade.Text("", 0, 0, arcade.color.GREEN, 10, bold=True)
        
        # Update positions and content
        self.title_text.x = window_width - 280
        self.title_text.y = window_height - 30
        self.title_text.draw()
        
        # FPS
        fps_color = arcade.color.GREEN if self.fps >= 58 else arcade.color.ORANGE if self.fps >= 45 else arcade.color.RED
        self.fps_text.text = f"FPS: {self.fps:.1f}"
        self.fps_text.color = fps_color
        self.fps_text.x = window_width - 280
        self.fps_text.y = window_height - 55
        self.fps_text.draw()
        
        # Frame time
        self.frame_text.text = f"Frame: {self.frame_ms:.2f}ms"
        self.frame_text.x = window_width - 280
        self.frame_text.y = window_height - 75
        self.frame_text.draw()
        
        # Draw time
        draw_color = arcade.color.GREEN if self.draw_ms < 10 else arcade.color.ORANGE if self.draw_ms < 14 else arcade.color.RED
        self.draw_text.text = f"Draw: {self.draw_ms:.2f}ms"
        self.draw_text.color = draw_color
        self.draw_text.x = window_width - 280
        self.draw_text.y = window_height - 95
        self.draw_text.draw()
        
        # Update time
        update_color = arcade.color.GREEN if self.update_ms < 5 else arcade.color.ORANGE if self.update_ms < 8 else arcade.color.RED
        self.update_text.text = f"Update: {self.update_ms:.2f}ms"
        self.update_text.color = update_color
        self.update_text.x = window_width - 280
        self.update_text.y = window_height - 115
        self.update_text.draw()
        
        # Ground draw time
        if self.ground_draw_ms > 0.1:
            self.ground_text.text = f"  Ground: {self.ground_draw_ms:.2f}ms"
            self.ground_text.x = window_width - 270
            self.ground_text.y = window_height - 135
            self.ground_text.draw()
        
        # Sprite draw time
        if self.sprite_draw_ms > 0.1:
            self.sprite_text.text = f"  Sprites: {self.sprite_draw_ms:.2f}ms"
            self.sprite_text.x = window_width - 270
            self.sprite_text.y = window_height - 155
            self.sprite_text.draw()
        
        # Texture loading time (CRITICAL - může způsobovat problémy!)
        if self.texture_load_ms > 0.1:
            tex_color = arcade.color.GREEN if self.texture_load_ms < 2 else arcade.color.ORANGE if self.texture_load_ms < 5 else arcade.color.RED
            self.texture_text.text = f"  Textures: {self.texture_load_ms:.2f}ms"
            self.texture_text.color = tex_color
            self.texture_text.x = window_width - 270
            self.texture_text.y = window_height - 175
            self.texture_text.draw()
        
        # Chunk processing time
        if self.chunk_process_ms > 0.1:
            self.chunk_text.text = f"  Chunks: {self.chunk_process_ms:.2f}ms"
            self.chunk_text.x = window_width - 270
            self.chunk_text.y = window_height - 195
            self.chunk_text.draw()
        
        # Network time
        if self.network_ms > 0.1:
            self.network_text.text = f"  Network: {self.network_ms:.2f}ms"
            self.network_text.x = window_width - 270
            self.network_text.y = window_height - 215
            self.network_text.draw()
        
        # Budget indicator
        budget_used = (self.draw_ms / 16.67) * 100
        budget_color = arcade.color.GREEN if budget_used < 60 else arcade.color.ORANGE if budget_used < 85 else arcade.color.RED
        self.budget_text.text = f"Budget: {budget_used:.0f}%"
        self.budget_text.color = budget_color
        self.budget_text.x = window_width - 280
        self.budget_text.y = window_height - 255
        self.budget_text.draw()
