"""
Stream handler for ChatGPT's progressive text rendering.

ChatGPT renders responses character-by-character (streaming).
This handler:
1. Detects new text additions
2. Tracks timing per chunk
3. Detects completion (stop button disappears)
"""

import time
from typing import Callable, Optional, List

from .models import StreamChunk


class StreamAccumulator:
    """Accumulates streaming text from ChatGPT DOM."""

    def __init__(self, on_chunk: Optional[Callable[[StreamChunk], None]] = None):
        self.chunks: List[StreamChunk] = []
        self.full_text = ""
        self.start_time_ms: Optional[float] = None
        self.first_token_time_ms: Optional[float] = None
        self.last_chunk_time_ms: Optional[float] = None
        self.on_chunk = on_chunk
        self._chunk_index = 0

    def process_text(self, current_text: str, is_streaming: bool) -> Optional[StreamChunk]:
        """Process current DOM text, emit chunk if new content."""
        now_ms = time.perf_counter() * 1000

        if self.start_time_ms is None:
            self.start_time_ms = now_ms

        # Detect new text
        if len(current_text) > len(self.full_text):
            new_text = current_text[len(self.full_text):]
            self.full_text = current_text

            if self.first_token_time_ms is None:
                self.first_token_time_ms = now_ms

            self.last_chunk_time_ms = now_ms

            chunk = StreamChunk(
                text=new_text,
                timestamp_ms=now_ms - self.start_time_ms,
                chunk_index=self._chunk_index,
                is_final=not is_streaming,
            )
            self._chunk_index += 1
            self.chunks.append(chunk)

            if self.on_chunk:
                self.on_chunk(chunk)

            return chunk

        return None

    def finalize(self) -> None:
        """Mark the last chunk as final."""
        if self.chunks and not self.chunks[-1].is_final:
            self.chunks[-1].is_final = True

    @property
    def ttft_ms(self) -> float:
        """Time to first token."""
        if self.start_time_ms and self.first_token_time_ms:
            return self.first_token_time_ms - self.start_time_ms
        return 0.0

    @property
    def stream_duration_ms(self) -> float:
        """Duration of streaming phase."""
        if self.first_token_time_ms and self.last_chunk_time_ms:
            return self.last_chunk_time_ms - self.first_token_time_ms
        return 0.0
