import pygame
from Player.Player import Projectile
velkost_plochy = 50

class Shooting_enemie(pygame.sprite.Sprite):
    def __init__(self, x, y, speed=2, patrol_blocks=2, image_path=None,tile_size=50):
        super().__init__()
        self.speed = speed
        base_img = self._load_image(image_path)

        base_img = pygame.transform.scale(base_img, (tile_size, tile_size))  # player texture rescaled to 50x50 as reference
        self.image_right = pygame.transform.flip(base_img, True, False)
        self.image_left = base_img
        self.image = self.image_right

        hit_w = max(8, int(round(tile_size * 0.6)))
        hit_h = max(8, int(round(tile_size * 0.9)))
        hit_x = x + (tile_size - hit_w) // 2
        hit_y = y + tile_size - hit_h
        self.rect = pygame.Rect(hit_x, hit_y, hit_w, hit_h)
        self.direction = 1  # 1 -> right, -1 -> left
        self.image_offset = ((self.image_right.get_width() - hit_w) // 2, self.image_right.get_height() - hit_h)
        # patrol
        self.start_x = self.rect.x
        self.patrol_blocks = patrol_blocks
        self.patrol_distance = patrol_blocks * tile_size

        # health left for compatibility but turret is indestructible
        self.health = 4
        # physics
        self.vel_y = 0
        # NEW: shooting cooldown (ms)
        self.last_shot_ms = 0
        self.shot_interval_ms = 900
        # NEW: cache for scaled images
        self._scale_cache = {"scale": None, "right": None, "left": None}

    def _load_image(self, image_path):
        # Try provided path, then common default, then fallback colored box
        candidates = [p for p in [image_path, r"Textures\Player.png"] if p]
        for p in candidates:
            try:
                return pygame.image.load(p).convert_alpha()
            except Exception:
                continue
        surf = pygame.Surface((50, 50), pygame.SRCALPHA)
        surf.fill((220, 40, 40, 255))
        return surf

    def update(self, player=None, projectiles=None, world=None):
        # Turret is stationary by default if speed==0; keep minimal collision checks so it rests on tiles
        intended_dx = self.speed * self.direction
        if intended_dx != 0:
            step_x = 1 if intended_dx > 0 else -1
            for _ in range(abs(intended_dx)):
                self.rect.x += step_x
                hit_wall = False
                # collide with world tiles
                if world:
                    for _, tile_rect in world.tile_list:
                        if self.rect.colliderect(tile_rect):
                            self.rect.x -= step_x
                            hit_wall = True
                            break

                if hit_wall:
                    self.direction *= -1
                    self.image = self.image_right if self.direction == 1 else self.image_left
                    break
                # clamp patrol bounds
                if self.rect.x > self.start_x + self.patrol_distance:
                    self.rect.x = self.start_x + self.patrol_distance
                    self.direction = -1
                    self.image = self.image_left
                    break
                elif self.rect.x < self.start_x:
                    self.rect.x = self.start_x
                    self.direction = 1
                    self.image = self.image_right
                    break


        # Gravity + vertical collision with tiles (pixel stepping)
        self.vel_y = min(self.vel_y + 1, 10)
        dy = self.vel_y
        if dy != 0:
            step_y = 1 if dy > 0 else -1
            for _ in range(abs(dy)):
                self.rect.y += step_y
                collided = False
                if world:
                    for _, tile_rect in world.tile_list:
                        if self.rect.colliderect(tile_rect):
                            self.rect.y -= step_y
                            self.vel_y = 0
                            collided = True
                            break
                if collided:
                    break

        # Face the player if provided

        # Shooting behavior: spawn enemy-owned projectile into provided projectiles group
        now_ms = pygame.time.get_ticks()
        if projectiles is not None and isinstance(projectiles, pygame.sprite.Group):
            if now_ms - self.last_shot_ms >= self.shot_interval_ms:
                # spawn projectile at turret barrel
                px = self.rect.right if self.direction == 1 else self.rect.left - Projectile.SIZE[0]
                py = self.rect.centery - Projectile.SIZE[1] // 2
                try:
                    proj = Projectile(px, py, self.direction, owner='enemy')
                    projectiles.add(proj)
                except Exception:
                    try:
                        w, h = max(1, Projectile.SIZE[0]), max(1, Projectile.SIZE[1])
                        pimg = pygame.Surface((w, h), pygame.SRCALPHA)
                        pimg.fill((255, 0, 0))
                        p = pygame.sprite.Sprite()
                        p.image = pimg
                        p.rect = pimg.get_rect(topleft=(px, py))
                        p.owner = 'enemy'
                        p.SPEED = getattr(Projectile, 'SPEED', 8)
                        p.direction = self.direction
                        # add a simple update that moves using the assigned direction
                        def _upd(self, world, screen_w=None, screen_h=None):
                            self.rect.x += (self.SPEED * (1 if getattr(self, 'direction', 1) > 0 else -1))
                        p.update = _upd.__get__(p)
                        projectiles.add(p)
                    except Exception:
                        pass
                self.last_shot_ms = now_ms

        if projectiles and isinstance(projectiles, pygame.sprite.Group):
            total_damage = 0
            for p in list(projectiles):
                try:
                    owner = getattr(p, 'owner', None)
                    if owner not in (None, 'player'):
                        continue
                    if p.rect.colliderect(self.rect):
                        try:
                            p.kill()
                        except Exception:
                            pass
                        dmg = getattr(p, "damage", 1)
                        total_damage += max(0, int(dmg))
                except Exception:
                    continue

            if total_damage > 0:
                self.health -= total_damage
                if self.health <= 0:
                    self.kill()
                    return

    # NEW: scaled draw with cache
    def draw(self, screen, scale, off_x=0, off_y=0):
        if self._scale_cache["scale"] != scale:
            self._scale_cache["scale"] = scale
            sw = max(1, int(round(self.image_right.get_width() * scale)))
            sh = max(1, int(round(self.image_right.get_height() * scale)))
            self._scale_cache["right"] = pygame.transform.smoothscale(self.image_right, (sw, sh))
            self._scale_cache["left"] = pygame.transform.smoothscale(self.image_left, (sw, sh))
        sx = int(round(self.rect.x * scale)) + off_x
        sy = int(round(self.rect.y * scale)) + off_y
        ox = int(round(self.image_offset[0] * scale))
        oy = int(round(self.image_offset[1] * scale))
        img = self._scale_cache["right"] if self.direction == 1 else self._scale_cache["left"]
        screen.blit(img, (sx - ox, sy - oy))
