import random

from engine.effects.types import EffectConfig, EffectContext, EffectPlugin


class FadeEffect(EffectPlugin):
    name = "fade"
    config = EffectConfig(enabled=True, intensity=1.0, entropy=0.1)

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

        top_zone = max(1, int(ctx.ticker_height * 0.25))
        bot_zone = max(1, int(ctx.ticker_height * 0.10))

        for r in range(len(result)):
            if r >= ctx.ticker_height:
                continue
            top_f = min(1.0, r / top_zone) if top_zone > 0 else 1.0
            bot_f = (
                min(1.0, (ctx.ticker_height - 1 - r) / bot_zone)
                if bot_zone > 0
                else 1.0
            )
            row_fade = min(top_f, bot_f) * intensity

            if row_fade < 1.0 and result[r].strip():
                result[r] = self._fade_line(result[r], row_fade)

        return result

    def _fade_line(self, s: str, fade: float) -> str:
        if fade >= 1.0:
            return s
        if fade <= 0.0:
            return s  # Preserve original line length - don't return empty
        result = []
        i = 0
        while i < len(s):
            if s[i] == "\033" and i + 1 < len(s) and s[i + 1] == "[":
                j = i + 2
                while j < len(s) and not s[j].isalpha():
                    j += 1
                result.append(s[i : j + 1])
                i = j + 1
            elif s[i] == " ":
                result.append(" ")
                i += 1
            else:
                result.append(s[i] if random.random() < fade else " ")
                i += 1
        return "".join(result)

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