import sys
import time

import pygame

from .screen import Screen
from .text import Text, Title

SCREEN_BG_COLOR = (50, 50, 50)

MOB_ASSETS = {
    'Yanaar': 'assets/orc.png',
    'Ulnarain': 'assets/orc2.jpg',
    'Skroll': 'assets/potato_man.jpg',
}

PLAYER_ASSET = 'assets/succube.png'


class PygameUi:

    def __init__(self):
        self.screen = Screen()
        self.show_title()

    def show_title(self):
        title = Title().set_position(center=self.screen.rect.center)
        space = Text('press space').set_position(midtop=title.rect.midbottom)

        loop_start = time.time()
        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)

            loop_time = time.time() - loop_start
            if loop_time % 2.0 > 1.0:
                space.show(self.screen.surface)

            self.screen.refresh()

    def empty_room(self):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('Room empty', font_size=48).set_position(center=inner_box.center)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            instructions.show(self.screen.surface)
            self.screen.refresh()

    def meet_mob(self, mob):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('Mob in the room', font_size=48).set_position(midtop=inner_box.midtop)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        spec_margin = 16
        spec_box = pygame.Rect(
            inner_box.left,
            title.rect.bottom + spec_margin,
            inner_box.width,
            instructions.rect.top - title.rect.bottom - (spec_margin * 2)
        )

        img = pygame.image.load(MOB_ASSETS[mob.name])
        img_rect = img.get_rect().fit(pygame.Rect(0, 0, spec_box.height, spec_box.height))
        img = pygame.transform.smoothscale(img, img_rect.size)
        img_rect = img.get_rect(midleft=spec_box.midleft)

        props_box = pygame.Rect(
            img_rect.right,
            spec_box.top,
            spec_box.width - img_rect.width,
            spec_box.height,
        )

        mob_name = Text(mob.name, font_size=36)
        mob_name = mob_name.set_position(midtop=props_box.midtop)

        mob_pv = Text(f"PV: {mob.current_pv}/{mob.max_pv}")
        mob_pv = mob_pv.set_position(top=mob_name.rect.bottom + 36, left=props_box.left + 16)

        mob_strength = Text(f"Force: {mob.strength}")
        mob_strength = mob_strength.set_position(top=mob_pv.rect.bottom + 24, left=props_box.left + 16)

        mob_protection = Text(f"Protection: {mob.protection}")
        mob_protection = mob_protection.set_position(top=mob_strength.rect.bottom + 24,
                                                     left=props_box.left + 16)

        mob_speed = Text(f"Vitesse: {mob.speed}")
        mob_speed = mob_speed.set_position(top=mob_protection.rect.bottom + 24, left=props_box.left + 16)

        texts = [
            title,
            mob_name,
            mob_pv,
            mob_strength,
            mob_protection,
            mob_speed,
            instructions,
        ]

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            self.screen.surface.blit(img, img_rect)
            for text in texts:
                text.show(self.screen.surface)
            self.screen.refresh()

    def player_dead(self):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('You are dead', font_size=48).set_position(center=inner_box.center)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            instructions.show(self.screen.surface)
            self.screen.refresh()

    def mob_dead(self, mob):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('You win', font_size=48).set_position(center=inner_box.center)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            instructions.show(self.screen.surface)
            self.screen.refresh()

    def run_away(self):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('You are running away', font_size=48).set_position(center=inner_box.center)

        for _ in range(60):  # 60 tick at 60fps => loop for 1sec
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            self.screen.refresh()

    def leave(self, player):
        title = Text(f'Goodbye {player.name}', font_size=48).set_position(center=self.screen.surface.get_rect().center)
        for _ in range(60):  # 60 tick at 60fps => loop for 1sec
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            self.screen.refresh()

    def select_player(self, player):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('Player selection', font_size=48).set_position(midtop=inner_box.midtop)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        spec_margin = 16
        spec_box = pygame.Rect(
            inner_box.left,
            title.rect.bottom + spec_margin,
            inner_box.width,
            instructions.rect.top - title.rect.bottom - (spec_margin * 2)
        )

        img = pygame.image.load(PLAYER_ASSET)
        img_rect = img.get_rect().fit(pygame.Rect(0, 0, spec_box.height, spec_box.height))
        img = pygame.transform.smoothscale(img, img_rect.size)
        img_rect = img.get_rect(midleft=spec_box.midleft)

        props_box = pygame.Rect(
            img_rect.right,
            spec_box.top,
            spec_box.width - img_rect.width,
            spec_box.height,
        )

        player_name = Text(player.name, font_size=36)
        player_name = player_name.set_position(midtop=props_box.midtop)

        player_pv = Text(f"PV: {player.current_pv}/{player.max_pv}")
        player_pv = player_pv.set_position(top=player_name.rect.bottom + 36, left=props_box.left + 16)

        player_strength = Text(f"Force: {player.strength}")
        player_strength = player_strength.set_position(top=player_pv.rect.bottom + 24, left=props_box.left + 16)

        player_protection = Text(f"Protection: {player.protection}")
        player_protection = player_protection.set_position(
            top=player_strength.rect.bottom + 24, left=props_box.left + 16)

        player_speed = Text(f"Vitesse: {player.speed}")
        player_speed = player_speed.set_position(top=player_protection.rect.bottom + 24, left=props_box.left + 16)

        texts = [
            title,
            player_name,
            player_pv,
            player_strength,
            player_protection,
            player_speed,
            instructions,
        ]

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            self.screen.surface.blit(img, img_rect)
            for text in texts:
                text.show(self.screen.surface)
            self.screen.refresh()

    def entering_room(self, room_name):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text(f'Room {room_name + 1}', font_size=48).set_position(center=inner_box.center)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            instructions.show(self.screen.surface)
            self.screen.refresh()

    def last_room(self):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('End of level', font_size=48).set_position(center=inner_box.center)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            instructions.show(self.screen.surface)
            self.screen.refresh()

    def entering_donjon(self, level):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text(f'Level 1 - {len(level.rooms)} rooms', font_size=48).set_position(center=inner_box.center)

        instructions = Text('Press enter to continue', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        loop = True
        while loop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        loop = False

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            instructions.show(self.screen.surface)
            self.screen.refresh()

    def action_menu(self, actions_autorisees):
        texts = [Text(action.libelle) for n, action in enumerate(actions_autorisees)]
        arrow = Text('> ')
        action_index = 0

        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('Select action', font_size=48).set_position(midtop=inner_box.midtop)

        instructions = Text('Press enter to continue; Press up or down to move arrow', font_size=24)
        instructions = instructions.set_position(left=inner_box.left, bottom=inner_box.bottom)

        action_box = pygame.Rect(inner_box.left + 64, title.rect.bottom + 64, inner_box.width, inner_box.height)
        last_bottom = action_box.top
        for text in texts:
            text.set_position(left=action_box.left, top=last_bottom)
            last_bottom = text.rect.bottom + 24

        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key in (pygame.K_KP_ENTER, pygame.K_RETURN):
                        return actions_autorisees[action_index]
                    elif event.key == pygame.K_DOWN:
                        action_index = min(action_index + 1, len(actions_autorisees) - 1)
                    elif event.key == pygame.K_UP:
                        action_index = max(action_index - 1, 0)

            self.screen.surface.fill(SCREEN_BG_COLOR)
            title.show(self.screen.surface)
            for text in texts:
                text.show(self.screen.surface)
            arrow.set_position(midright=texts[action_index].rect.midleft).show(self.screen.surface)
            instructions.show(self.screen.surface)
            self.screen.refresh()

    def fight_pvs(self, player, mob, pvs):
        margin = 16
        inner_box = pygame.Rect(margin, margin, self.screen.width - (margin * 2), self.screen.height - (margin * 2))

        title = Text('Fight', font_size=48).set_position(midtop=inner_box.midtop)

        player_img = pygame.image.load(PLAYER_ASSET)
        player_img_rect = player_img.get_rect().fit(pygame.Rect(0, 0, 128, 128))
        player_img = pygame.transform.smoothscale(player_img, player_img_rect.size)
        player_img_rect = player_img.get_rect(left=inner_box.left + 48, centery=inner_box.centery)

        mob_img = pygame.image.load(MOB_ASSETS[mob.name])
        mob_img_rect = mob_img.get_rect().fit(pygame.Rect(0, 0, 128, 128))
        mob_img = pygame.transform.smoothscale(mob_img, mob_img_rect.size)
        mob_img_rect = mob_img.get_rect(right=inner_box.right - 48, centery=inner_box.centery)

        init_fight = [{
            'player': player.max_pv,
            'mob': mob.max_pv,
        }]

        all_pvs = init_fight + pvs

        for pv in all_pvs:
            for _ in range(60):  # 60 tick at 60fps => loop for 1sec
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        sys.exit()

                self.screen.surface.fill(SCREEN_BG_COLOR)
                title.show(self.screen.surface)
                self.screen.surface.blit(player_img, player_img_rect)
                self.screen.surface.blit(mob_img, mob_img_rect)

                (Text(f"{pv['player']}/{player.max_pv}", font_size=36)
                 .set_position(midtop=player_img_rect.midbottom)
                 .show(self.screen.surface))
                (Text(f"{pv['mob']}/{mob.max_pv}", font_size=36)
                 .set_position(midtop=mob_img_rect.midbottom)
                 .show(self.screen.surface))

                self.screen.refresh()
