"""Fast chunker powered by chonkie-core."""

from typing import Any, Dict, List, Optional, Sequence

import chonkie_core

from chonkie.chunker.base import BaseChunker
from chonkie.pipeline import chunker
from chonkie.types import Chunk


@chunker("fast")
class FastChunker(BaseChunker):
    r"""Fast byte-based chunker using SIMD-accelerated boundary detection.

    Unlike other chonkie chunkers that use token counts, FastChunker uses
    byte size limits for maximum performance (~100+ GB/s throughput).

    This is a thin wrapper around chonkie-core's chunking functionality.

    Args:
        chunk_size: Target chunk size in bytes (default: 4096)
        delimiters: Delimiter characters for splitting (default: "\n.?")
        pattern: Multi-byte pattern to split on (overrides delimiters)
        prefix: Put delimiter at start of next chunk (default: False)
        consecutive: Split at START of consecutive runs (default: False)
        forward_fallback: Search forward if no delimiter in backward window

    Example:
        >>> chunker = FastChunker(chunk_size=1024)
        >>> chunks = chunker("Your long document here...")
        >>> for chunk in chunks:
        ...     print(chunk.text[:50])

    """

    def __init__(
        self,
        chunk_size: int = 4096,
        delimiters: str = "\n.?",
        pattern: Optional[str] = None,
        prefix: bool = False,
        consecutive: bool = False,
        forward_fallback: bool = False,
    ):
        """Initialize the FastChunker."""
        # Don't call super().__init__() - we don't need a tokenizer
        # But set required attributes for BaseChunker compatibility
        self._tokenizer = None
        self._use_multiprocessing = False

        self.chunk_size = chunk_size
        self.delimiters = delimiters
        self.pattern = pattern
        self.prefix = prefix
        self.consecutive = consecutive
        self.forward_fallback = forward_fallback

    def __repr__(self) -> str:
        """Return a string representation of the chunker."""
        return (
            f"FastChunker(chunk_size={self.chunk_size}, delimiters={self.delimiters!r}, "
            f"pattern={self.pattern!r}, prefix={self.prefix}, "
            f"consecutive={self.consecutive}, forward_fallback={self.forward_fallback})"
        )

    def chunk(self, text: str) -> List[Chunk]:
        """Chunk text at delimiter boundaries.

        Args:
            text: Input text to chunk

        Returns:
            List of Chunk objects

        """
        if not text:
            return []

        # Build kwargs for chonkie-core
        kwargs: Dict[str, Any] = {
            "size": self.chunk_size,
            "prefix": self.prefix,
            "consecutive": self.consecutive,
            "forward_fallback": self.forward_fallback,
        }

        if self.pattern:
            kwargs["pattern"] = self.pattern
        else:
            kwargs["delimiters"] = self.delimiters

        # Encode to bytes for chonkie-core (which works with byte offsets)
        text_bytes = text.encode("utf-8")

        # Get chunk offsets from chonkie-core (these are byte offsets)
        offsets = chonkie_core.chunk_offsets(text_bytes, **kwargs)

        # Convert to Chunk objects by slicing bytes and decoding
        # Track character position to convert byte offsets to char offsets
        chunks = []
        char_pos = 0
        for start, end in offsets:
            chunk_text = text_bytes[start:end].decode("utf-8")
            chunk_char_len = len(chunk_text)
            chunks.append(
                Chunk(
                    text=chunk_text,
                    start_index=char_pos,
                    end_index=char_pos + chunk_char_len,
                    token_count=0,
                )
            )
            char_pos += chunk_char_len
        return chunks

    def chunk_batch(self, texts: Sequence[str], show_progress: bool = True) -> List[List[Chunk]]:
        """Chunk a batch of texts.

        Args:
            texts: The texts to chunk.
            show_progress: Whether to show progress (ignored, always fast).

        Returns:
            A list of lists of Chunks.

        """
        return [self.chunk(text) for text in texts]
