import json
import sys
import os

from enne2engine import engine
from Entities.Units.marine import Marine

class Game:
    def __init__(self):
        self.engine = engine.GameEngine(self.load_map(), self)

        self.frame_time = 0
        self.cursor_pos = (0, 0)
        
        self.load_assets()
        self.entities = []
        self.entities_positions = {}

    def run(self):
        running = True
        # Set a custom scale if needed
        self.engine.graphics.set_scaling_factor(1.0)  # 50% scale
        marine = Marine("knight", 0, 0, "idle", 1, 1, self)
        self.entities.append(marine)
        # self.entities.append(Marine("knight", 5, 5, "idle", 1, 1, self))
        # #5 more marines
        # self.entities.append(Marine("knight", 0, 5, "idle", 1, 1, self))
        # self.entities.append(Marine("knight", 5, 5, "idle", 1, 1, self))
        # self.entities.append(Marine("knight", 1,1, "idle", 1, 1, self))
        # self.entities.append(Marine("knight", 2,2, "idle", 1, 1, self))
        # self.entities.append(Marine("knight", 3,3, "idle", 1, 1, self))
        while running:
            self.cmd_sound_effects = False
            # Start the frame timer
            perf_counter = self.engine.graphics.get_perf_counter()
            # Initialize the map shadow and entities positions
            self.map_shadow = [ [1 for _ in range(len(self.engine.map[0]))] for _ in range(len(self.engine.map)) ]
            self.entities_positions.clear()
            for entity in self.entities:
                self.entities_positions[entity.next_cell] = entity
                self.entities_positions[(entity.x, entity.y)] = entity
            
            # Handle events
            event = self.engine.graphics.handle_events()
            if event:
                #print(f"Event detected: {event}")
                if event.startswith("MOUSEDOWN"):       
                    print(f"Mouse down event: {event}")
                    print(f"Button pressed: {event[-1]}")
                    if event[-1] == "3":
                        print("Right mouse button pressed")
                        for entity in self.entities:
                            if entity.selected:
                                entity.set_target_cell(self.cursor_pos)
                elif event.startswith("SELECTION"):
                    # Handle multiple unit selection
                    self.select_units_in_area(event)
                elif event.startswith("MOUSEUP"):
                    if event[-1] == "1":
                    
                        self.select_entity_at_cursor()
                self.engine.handle_events("keymap_game", event)
                
            running = False if event == "QUIT" else True
            
            self.engine.graphics.clear_screen()
            
            for entity in self.entities:
                entity.update()
            # Create the map background texture with tiles
            self.engine.graphics.create_background(self.engine.map, "tiles", self.map_shadow)
            self.cursor_pos = self.engine.graphics.draw_cursor()
            
            self.engine.graphics.render_background()
            self.engine.graphics.render_sprites()
            self.engine.graphics.draw_selection_rectangle()
            self.engine.graphics.update_status(f"Frame time: {round(self.frame_time)}ms - FPS: {round(1000/self.frame_time if self.frame_time != 0 else 1)}")
            self.engine.graphics.present_renderer()
            self.frame_time = self.engine.graphics.get_frame_time(perf_counter)
            self.engine.graphics.delay_frame(self.frame_time,50)
        self.engine.graphics.quit()
        
    def set_cursor(self, x, y):
        self.engine.graphics.cursor = (x, y)    
    
    def load_assets(self):
        self.engine.graphics.load_tilesheet("tiles", "assets/tiles/landscapeTiles_sheet.png")
        for dir in os.listdir("assets/KnightBasic"):
            for file in os.listdir(f"assets/KnightBasic/{dir}"):
                    if file.endswith(".json"):
                        self.engine.graphics.load_spritesheet(file[:-5].lower(), f"assets/KnightBasic/{dir}/{file}")
        
    def select_entity_at_cursor(self):
        cursor_x, cursor_y = self.cursor_pos
        print(f"Cursor position: {cursor_x}, {cursor_y}")
        # First deselect all entities
        for entity in self.entities:
            entity.selected = False
        
        # Then select the entity at cursor position, if any
        entity = self.entities_positions.get((cursor_x, cursor_y))
        if entity:
            entity.select_unit()
            print(f"Selected entity at cursor: {entity.asset} at position {entity.x}, {entity.y}")
        else:
            print("No entity selected at cursor position.")
    
    def select_units_in_area(self, selection_event):
        """Select all units within the specified selection area."""
        # Parse selection coordinates
        _, start_x, start_y, end_x, end_y = selection_event.split(":")
        start_x, start_y, end_x, end_y = int(start_x), int(start_y), int(end_x), int(end_y)
        
        # Calculate selection rectangle in screen coordinates
        min_x = min(start_x, end_x)
        max_x = max(start_x, end_x)
        min_y = min(start_y, end_y)
        max_y = max(start_y, end_y)
        
        # First deselect all entities
        for entity in self.entities:
            entity.selected = False
        
        # Select entities within the rectangle
        for entity in self.entities:
            # Convert entity position to screen coordinates
            screen_x, screen_y = self.engine.graphics.iso_transform(entity.x, entity.y)
            
            # Check if entity is within selection rectangle
            if min_x <= screen_x <= max_x and min_y <= screen_y <= max_y:
                entity.select_unit()
                print(f"Selected entity in area: {entity.asset} at position {entity.x}, {entity.y}")

    def load_map(self):
                # Load map from JSON file
        try:
            with open("assets/maps/map.json", "r") as map_file:
                return json.load(map_file)
        except (FileNotFoundError, json.JSONDecodeError) as e:
            print(f"Error loading map file: {e}")
            print("Exiting program.")
            sys.exit(0)

if __name__ == "__main__":
    game = Game()
    game.run()