import random

from engine import config
from engine.effects.types import EffectConfig, EffectContext, EffectPlugin
from engine.terminal import C_DIM, G_DIM, G_LO, RST, W_GHOST


class NoiseEffect(EffectPlugin):
    name = "noise"
    config = EffectConfig(enabled=True, intensity=0.15, entropy=0.4)

    def process(self, buf: list[str], ctx: EffectContext) -> list[str]:
        if not ctx.ticker_height:
            return buf
        result = list(buf)
        intensity = self.config.intensity
        probability = intensity * 0.15

        for r in range(len(result)):
            cy = ctx.scroll_cam + r
            if random.random() < probability:
                original_line = result[r]
                result[r] = self._generate_noise(len(original_line), cy)
        return result

    def _generate_noise(self, w: int, cy: int) -> str:
        d = random.choice([0.15, 0.25, 0.35, 0.12])
        return "".join(
            f"{random.choice([G_LO, G_DIM, C_DIM, W_GHOST])}"
            f"{random.choice(config.GLITCH + config.KATA)}{RST}"
            if random.random() < d
            else " "
            for _ in range(w)
        )

    def configure(self, config: EffectConfig) -> None:
        self.config = config
