import pygame
import time
pygame.init()


class Bullet:
    def __int__(self, loc):
        self.image = pygame.Surface((20, 20)).convert()
        self.image.fill((255, 255, 0))
        self.rect = self.image.get_rect(center=loc)
        self.speed = 5


class Player:
    def __init__(self, x, y, data, sprite_sheet, fps):
        self.action = 2  # 0 = punch 4 = walk, 2 = idle
        self.frame_index = 0
        self.size = data[0]
        self.image_scale = data[1]
        self.offset = data[2]
        self.animation_list = self.load_sprites(sprite_sheet, fps)
        self.image = self.animation_list[self.action][self.frame_index]
        self.update_time = pygame.time.get_ticks()
        self.running = False
        self.jump = False
        self.flip = False
        self.attack_type = 0
        self.rect = pygame.Rect(x, y, 120, 240)
        self.attacking = False
        self.attack_cooldown = 0
        self.health = 200
        self.vel_y = 0
        self.stun = False
        self.dead = False
        self.shooting = False
        self.Bullet_Vel = 6
        self.bullet_on_screen = False

    def load_sprites(self, sprite_sheet, fps):
        animation_list = []
        for y, frame in enumerate(fps):
            temp_img_list = []
            for x in range(frame):
                temp_img = sprite_sheet.subsurface(x * self.size, y * self.size, self.size, self.size)
                temp_img_list.append(pygame.transform.scale(temp_img, (self.size * self.image_scale, self.size *
                                                                       self.image_scale)))
            animation_list.append(temp_img_list)
        return animation_list

    def controls(self, surface, target,):
        PLAYER_VEL = 10
        dx = 0
        dy = 0
        Grav = 2
        self.running = False
        self.attack_type = 0

        # looks for keys getting pressed
        Key = pygame.key.get_pressed()

        if Key[pygame.K_a] and self.rect.x - PLAYER_VEL >= 0:
            dx = -PLAYER_VEL
            self.running = True
        if Key[pygame.K_d] and self.rect.right <= 1540:
            dx = PLAYER_VEL
            self.running = True
        # jumping
        if Key[pygame.K_w] and self.rect.bottom >= 820:
            self.vel_y = -35
            dy += self.vel_y
            self.vel_y += Grav
            self.jump = True

        # Attacks1
        if Key[pygame.K_e] and self.attacking is False:
            self.attack(surface, target)
        if Key[pygame.K_r] and self.attacking is False:
            self.attack2(surface, target)
        if Key[pygame.K_f] and self.attacking is False:
            pass # call bullet function
        # stopping player from falling off-screen
        if self.rect.bottom >= 850:
            self.vel_y = 0
            self.rect.bottom = 851
            self.jump = False
        # make players face each other
        if target.rect.centerx > self.rect.centerx:
            self.flip = False
        else:
            self.flip = True

        # apply attack cooldown
        if self.attack_cooldown > 0:
            self.attack_cooldown -= 1
        # Attacks2
        if Key[pygame.K_e]:
            self.attack_type = 1
            print(self.attack_type)
        if Key[pygame.K_r]:
            self.attack_type = 2
            print(self.attack_type)
        # apply Gravity
        dy += self.vel_y
        self.vel_y += Grav

        # update player position
        self.rect.x += dx
        self.rect.y += dy

    def update(self):
        if self.shooting is True:
            self.update_action(5)
        elif self.health <= 0:
            self.health = 0
            self.dead = True
            self.update_action(7)
        elif self.stun is True:
            self.update_action(6) # stun
        elif self.attacking is True:
            if self.attack_type == 1: # punch
                self.update_action(0)
            elif self.attack_type == 2: # kick
                self.update_action(3)
        elif self.jump is True:
            self.update_action(1)
        elif self.running is True:
            self.update_action(4)
        else:
            self.update_action(2) # idle

        animation_cooldown = 100
        self.image = self.animation_list[self.action][self.frame_index]
        if pygame.time.get_ticks() - self.update_time > animation_cooldown:
            self.frame_index += 1
            self.update_time = pygame.time.get_ticks()
        if self.frame_index >= len(self.animation_list[self.action]):
            self.frame_index = 0
        # player death
            if self.dead is True:
                self.frame_index = len(self.animation_list[self.action]) - 1
            else:
        # check if an attack was executed
                if self.action == 0 or self.action == 3:
                    self.attacking = False
                    self.attack_cooldown = 10
                if self.action == 6:
                    self.stun = False
                # move cancelling
                    self.attacking = False
                    self.attack_cooldown = 10
                if self.action == 5:
                    self.shooting = False

    def attack(self, surface, target):
        self.attacking = True
        if self.attacking is True:
            attack_hitbox = pygame.Rect(self.rect.centerx - (2 * self.rect.width * self.flip),
                                        self.rect.y, 2 * self.rect.width, 0.5 * self.rect.height)
            if attack_hitbox.colliderect(target.rect):
                target.health -= 10
                target.stun = True
            pygame.draw.rect(surface, "Red", attack_hitbox)

    def attack2(self, surface, target):
        self.attacking = True
        if self.attacking is True:
            attack_hitbox = pygame.Rect(self.rect.centerx - (2 * self.rect.width * self.flip),
                                        self.rect.y, 2 * self.rect.width, 0.5 * self.rect.height)
            if attack_hitbox.colliderect(target.rect):
                target.health -= 10
                target.stun = True
            pygame.draw.rect(surface, "Red", attack_hitbox)

    def update_action(self, new_action):
        if new_action != self.action:
            self.action = new_action
            self.frame_index = 0
            self.update_time = pygame.time.get_ticks()

    def draw(self, surface):
        img = pygame.transform.flip(self.image, self.flip, False)
        pygame.draw.rect(surface, "Yellow", self.rect)
        surface.blit(img, (self.rect.x - (self.offset[0] * self.image_scale), self.rect.y - (self.offset[1] *
                                                                                             self.image_scale)))

