"""Chunking strategie pro indexing textových souborů."""

from __future__ import annotations

import hashlib
import logging
from dataclasses import dataclass
from pathlib import Path

from cyberbrain26.knowledge_plane.embedding_config import EmbeddingConfig

logger = logging.getLogger(__name__)


@dataclass(frozen=True)
class Chunk:
    """Jeden chunk textu."""

    text: str
    chunk_index: int
    source_path: str
    mtime: float
    sha256: str


class TextChunker:
    """Dělí text na chunky podle velikosti a překryvu."""

    def __init__(self, config: EmbeddingConfig | None = None) -> None:
        self.config = config or EmbeddingConfig()

    @staticmethod
    def _file_sha256(path: Path) -> str:
        """Vrátí SHA256 souboru."""
        h = hashlib.sha256()
        with path.open("rb") as f:
            for chunk in iter(lambda: f.read(65536), b""):
                h.update(chunk)
        return h.hexdigest()

    def chunk_file(self, path: Path) -> list[Chunk]:
        """Načte soubor a rozdelí ho na chunky."""
        return self.chunk_text(path.read_text(encoding="utf-8", errors="replace"), source_path=str(path))

    def chunk_text(self, text: str, source_path: str = "<memory>") -> list[Chunk]:
        """Rozdělí text na chunky bez zápisu na disk."""
        tokens = text.split()
        size = self.config.chunk_size_tokens
        overlap = self.config.chunk_overlap_tokens
        step = size - overlap
        chunks: list[Chunk] = []
        index = 0
        start = 0
        while start < len(tokens):
            end = start + size
            chunk_tokens = tokens[start:end]
            chunk_text = " ".join(chunk_tokens)
            chunks.append(
                Chunk(
                    text=chunk_text,
                    chunk_index=index,
                    source_path=source_path,
                    mtime=0.0,
                    sha256="",
                )
            )
            index += 1
            start += step
            if step <= 0:
                break
        logger.info("Rozděleno text na %d chunů", len(chunks))
        return chunks
