import pygame 
from pygame.locals import *

from Classes.Objects.Cards.MonsterCard import MonsterCard
from Classes.System.Components.Window import Window
from Classes.System.Components.InputHandler import InputHandler
from Classes.Objects.World import World
from Classes.System.Network.NetworkManager import NetworkManager

class App:

    __window:Window
    __running:bool = True
    __FPS = 60
    __clock = pygame.time.Clock()
    __myFont:pygame.font
    __world:World
    __inputHandler: InputHandler
    __networkManager: NetworkManager

    def __init__(self, width:int=1920, height:int=1080, title:str="default title"):
        pygame.font.init() 
        self.__myFont = pygame.font.SysFont('Comic Sans MS', 30)
        self.__window = Window(width=width, height=height, title=title)
        self.__inputHandler = InputHandler()
        self.__networkManager("127.0.0.1", "54322", "54323")
        
        # game word
        self.__world = World(self.__window.getScreen())

        self.startGameLoop()
        self.onCleanup()

    def startGameLoop(self):

        # create sprite groups
        # todo: remove these and let server handle card creation instead
        # blocker: server - client communication [WIP]
        self.__world.spawnCard("Assets/Cards/MonsterCards/testmonstercard/", (pygame.Vector2(500, 1050), self.__inputHandler))
        self.__world.spawnCard("Assets/Cards/MonsterCards/testmonstercard/", (pygame.Vector2(600, 1050), self.__inputHandler))
        self.__world.spawnCard("Assets/Cards/MonsterCards/testmonstercard/", (pygame.Vector2(700, 1050), self.__inputHandler))
        self.__world.spawnCard("Assets/Cards/MonsterCards/testmonstercard/", (pygame.Vector2(800, 1050), self.__inputHandler))
        self.__world.spawnCard("Assets/Cards/MonsterCards/testmonstercard/", (pygame.Vector2(900, 1050), self.__inputHandler))
        self.__world.spawnCard("Assets/Cards/MonsterCards/testmonstercard/", (pygame.Vector2(1000, 1050), self.__inputHandler))

        while self.__running:
            self.__clock.tick(self.__FPS)

            self.__window.getScreen().fill((0,0,0))

            # render world
            self.__window.drawWorld(self.__world)

            # updates all cards inside the cards Spritegroup at each step the gameloops does
            self.__world.getCards().update()

            # draw groups
            self.__window.drawSpriteGroup(self.cards)

            # event handler
            self.handleEvent(pygame.event.get())

            # emits update to the game
            pygame.display.update()

    # handles incoming event queue
    def handleEvent(self, events):
        # TODO: fix bug that stacks cards when dragging them around
        selectedCard = None
        
        for event in events:
            if event.type == pygame.QUIT:
                self.onCleanup()
            elif pygame.mouse.get_pressed()[0]:  # Wenn linke Maustaste gedrückt wird
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    mouse_pos = pygame.Vector2(mouse_x, mouse_y)

                    for card in self.__world.getCards():
                        if card.rect.collidepoint(mouse_pos) and selectedCard == None:
                            card.setDragging(True)
                            selectedCard = card

                            for field in self.__world.getBoardFields():
                                if field.getRect().collidepoint(mouse_pos):
                                    if field.getSide() == "Player":
                                        if field.getType() == "MonsterField" and card.getType() == "MonsterCard":
                                            # todo: resize card so that it fits into the card field
                                            card.rect.center = field.rect.center
                                            field.image = card.image.copy()
                                            card.setDragging(False)
                                        elif field.getType() == "EffectField" and card.getType() == "SpellCard" or field.getType() == "EffectField" and card.getType() == "TrapCard":
                                            # todo: resize card so that it fits into the card field
                                            card.rect.center = field.rect.center
                                            field.image = card.image.copy()
                                            card.setDragging(False)

            elif event.type == pygame.MOUSEBUTTONUP:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                mouse_pos = pygame.Vector2(mouse_x, mouse_y)
                if event.button == 1:  # Wenn linke Maustaste losgelassen wird
                    for card in self.__world.getCards():
                        card.setDragging(False)
                        # TODO: send server command
                        if not card == None:
                            card = None 

    # sets the running state for the gameloop
    def setRunning(self, running:bool):
        self.__running = running

    # ensures the gameloop stops running and the pygame instance is stopped properly
    def onCleanup(self):
        self.__running = False
        pygame.quit()