"""Wand-Tile Klasse mit Wellen-System und Rand-Erkennung."""
import pyxel
import math
import random
from constants import (
    SCREEN_W, SCREEN_H, TILE, COLS, ROWS,
    WALL_INNER_INSET, WALL_INNER_SIZE,
    HEDGE_U, HEDGE_V, COL_GREEN, COL_DARK,
    WAVE_COUNT, WAVE_PAUSE_FRAMES, WAVE_SCATTER_FRAMES
)


def dist(ax, ay, bx, by):
    return math.hypot(ax - bx, ay - by)


def is_border_wall(col, row):
    """Prüft ob ein Tile am Rand des Spielfelds liegt."""
    return row == 0 or row == ROWS - 1 or col == 0 or col == COLS - 1


class WallPiece:
    """Einzelnes 16x16-Wand-Tile.
    Randwaende starten sofort eingerastet.
    Innere Waende fliegen in Wellen ein mit individueller Verzoegerung."""

    SNAP_DIST = 2.0

    def __init__(self, col, row, speed, delay=0):
        self.tx = col * TILE
        self.ty = row * TILE
        self.snapped = False
        self.delay = delay
        self.active = False
        self.is_border = is_border_wall(col, row)

        # Randwaende sind sofort da
        if self.is_border:
            self.x = self.tx
            self.y = self.ty
            self.snapped = True
            self.active = True
            self.vx = 0
            self.vy = 0
            return

        # Startposition: zufaellige Seite
        side = random.randint(0, 3)
        if side == 0:
            self.x = random.uniform(-TILE, SCREEN_W)
            self.y = random.uniform(-TILE * 8, -TILE * 2)
        elif side == 1:
            self.x = random.uniform(-TILE, SCREEN_W)
            self.y = random.uniform(SCREEN_H + TILE * 2, SCREEN_H + TILE * 8)
        elif side == 2:
            self.x = random.uniform(-TILE * 8, -TILE * 2)
            self.y = random.uniform(-TILE, SCREEN_H)
        else:
            self.x = random.uniform(SCREEN_W + TILE * 2, SCREEN_W + TILE * 8)
            self.y = random.uniform(-TILE, SCREEN_H)

        dx = self.tx - self.x
        dy = self.ty - self.y
        d  = math.hypot(dx, dy) or 1
        s  = speed * 0.6 * random.uniform(0.7, 1.3)
        self.vx = dx / d * s
        self.vy = dy / d * s

    def update(self):
        if self.snapped:
            return

        # Verzoegerung herunterzaehlen
        if not self.active:
            self.delay -= 1
            if not (self.delay > 0):
                self.active = True
            return

        # Fliegen
        self.x += self.vx
        self.y += self.vy
        if self.SNAP_DIST > dist(self.x, self.y, self.tx, self.ty):
            self.x = self.tx
            self.y = self.ty
            self.snapped = True

    def draw(self, has_res):
        if not self.active and not self.snapped:
            return

        ix, iy = int(self.x), int(self.y)
        if has_res:
            pyxel.blt(ix, iy, 1, HEDGE_U, HEDGE_V, TILE, TILE, 0)
        else:
            pyxel.rect(ix + WALL_INNER_INSET, iy + WALL_INNER_INSET,
                       WALL_INNER_SIZE, WALL_INNER_SIZE, COL_GREEN)
            pyxel.rectb(ix, iy, TILE, TILE, COL_DARK)

    def pixel_rect(self):
        return (int(self.x) + WALL_INNER_INSET,
                int(self.y) + WALL_INNER_INSET,
                WALL_INNER_SIZE, WALL_INNER_SIZE)


def create_wall_pieces(level_map, speed):
    """Erstellt alle WallPieces mit Wellen-Verzoegerung."""
    wall_pieces = []
    inner_positions = []

    for row, line in enumerate(level_map):
        for col, ch in enumerate(line):
            if ch == '#':
                if is_border_wall(col, row):
                    wall_pieces.append(WallPiece(col, row, speed, delay=0))
                else:
                    inner_positions.append((col, row))

    random.shuffle(inner_positions)
    walls_per_wave = max(1, len(inner_positions) // WAVE_COUNT)

    for i, (col, row) in enumerate(inner_positions):
        wave_index = min(i // walls_per_wave, WAVE_COUNT - 1)
        base_delay = wave_index * WAVE_PAUSE_FRAMES
        scatter = random.randint(0, WAVE_SCATTER_FRAMES)
        delay = base_delay + scatter
        wall_pieces.append(WallPiece(col, row, speed, delay=delay))

    return wall_pieces
