import re
from typing import List


class TextPreprocessor:
    """Handles text preprocessing and chunking."""

    def preprocess_text(self, text: str) -> str:
        """Normalize and clean text content.

        Args:
            text: Raw text content

        Returns:
            Cleaned and normalized text
        """
        # Remove extra whitespace
        text = re.sub(r"\s+", " ", text.strip())

        # Remove special characters but keep basic punctuation
        text = re.sub(r"[^a-zA-Z0-9\s.,!?]", "", text)

        # Split into sentences based on any punctuation that ends a sentence,
        # keeping the punctuation with the sentence
        sentences = re.findall(r"[^.!?]+[.!?]", text)

        # Remove extra whitespace from each sentence and add newline
        processed_sentences = [s.strip() + "\n" for s in sentences]

        return "".join(processed_sentences).strip()

    def _process_single_sentence(self, sentence: str, chunk_size: int) -> List[str]:
        """Process a single sentence that exceeds chunk size."""
        chunks = []
        words = sentence.split()
        current_chunk = []
        current_length = 0

        for word in words:
            word_len = len(word) + 1  # +1 for space
            if current_length + word_len > chunk_size:
                if current_chunk:
                    chunks.append(" ".join(current_chunk))
                current_chunk = [word]
                current_length = word_len
            else:
                current_chunk.append(word)
                current_length += word_len

        if current_chunk:
            chunks.append(" ".join(current_chunk))
        return chunks

    def split_into_chunks(self, text: str, chunk_size: int = 500) -> List[str]:
        """Split text into chunks of approximately equal size."""
        if not text or not text.strip():
            return []

        # Split into sentences first
        sentences = re.split(r"(?<=[.!?])\s+", text)
        chunks = []
        current_chunk = []
        current_length = 0

        for sentence in sentences:
            sentence_length = len(sentence)

            # If single sentence is longer than chunk_size, split it
            if sentence_length > chunk_size:
                if current_chunk:
                    chunks.append(" ".join(current_chunk))
                    current_chunk = []
                    current_length = 0

                chunks.extend(self._process_single_sentence(sentence, chunk_size))
                continue

            # Regular sentence handling
            if current_length + sentence_length + 1 > chunk_size:
                if current_chunk:
                    chunks.append(" ".join(current_chunk))
                current_chunk = [sentence]
                current_length = sentence_length
            else:
                current_chunk.append(sentence)
                current_length += sentence_length + 1

        # Add the last chunk if it exists
        if current_chunk:
            chunks.append(" ".join(current_chunk))

        return chunks
