from __future__ import annotations

from typing import Optional

import structlog

from rasa.core.channels.voice_stream.asr.asr_event import InterimTranscriptReady

logger = structlog.get_logger()

DEFAULT_MIN_NEW_TOKENS = 3


class InterimTranscriptBuffer:
    """Buffers UserIsSpeaking events and emits InterimTranscriptReady
    when enough new tokens have accumulated since the last emission."""

    def __init__(self, min_new_tokens: int = DEFAULT_MIN_NEW_TOKENS) -> None:
        self.min_new_tokens = min_new_tokens
        self._last_emitted_text: str = ""

    def on_user_is_speaking(self, text: str) -> Optional[InterimTranscriptReady]:
        """Process an interim transcript and emit InterimTranscriptReady if threshold met.

        Args:
            text: The current interim transcript text.

        Returns:
            InterimTranscriptReady event if enough new tokens accumulated, else None.
        """
        if not text:
            return None

        new_token_count = self._count_new_tokens(text)
        if new_token_count >= self.min_new_tokens:
            self._last_emitted_text = text
            logger.debug(
                "speculative.buffer.emit",
                text=text,
                new_tokens=new_token_count,
            )
            return InterimTranscriptReady(text=text, token_count=new_token_count)

        return None

    def reset(self) -> None:
        """Reset buffer state. Called when a final transcript arrives."""
        self._last_emitted_text = ""

    def _count_new_tokens(self, current_text: str) -> int:
        """Count the number of new whitespace-delimited tokens."""
        current_tokens = current_text.split()
        last_tokens = self._last_emitted_text.split()
        return len(current_tokens) - len(last_tokens)
