import random

from engine.effects.types import EffectConfig, EffectContext, EffectPlugin
from engine.terminal import DIM, G_LO, RST


class GlitchEffect(EffectPlugin):
    name = "glitch"
    config = EffectConfig(enabled=True, intensity=1.0, entropy=0.8)

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

        glitch_prob = 0.32 + min(0.9, ctx.mic_excess * 0.16)
        glitch_prob = glitch_prob * intensity
        n_hits = 4 + int(ctx.mic_excess / 2)
        n_hits = int(n_hits * intensity)

        if random.random() < glitch_prob:
            # Store original visible lengths before any modifications
            # Strip ANSI codes to get visible length
            import re

            ansi_pattern = re.compile(r"\x1b\[[0-9;]*[a-zA-Z]")
            original_lengths = [len(ansi_pattern.sub("", line)) for line in result]
            for _ in range(min(n_hits, len(result))):
                gi = random.randint(0, len(result) - 1)
                result[gi]
                target_len = original_lengths[gi]  # Use stored original length
                glitch_bar = self._glitch_bar(target_len)
                result[gi] = glitch_bar
        return result

    def _glitch_bar(self, target_len: int) -> str:
        c = random.choice(["░", "▒", "─", "\xc2"])
        n = random.randint(3, max(3, target_len // 2))
        o = random.randint(0, max(0, target_len - n))

        glitch_chars = c * n
        trailing_spaces = target_len - o - n
        trailing_spaces = max(0, trailing_spaces)

        glitch_part = f"{G_LO}{DIM}" + glitch_chars + RST
        result = " " * o + glitch_part + " " * trailing_spaces

        return result

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