from __future__ import annotations

import hashlib
import math


def deterministic_embedding(text: str, dim: int = 128) -> list[float]:
    """Build a deterministic lightweight embedding without external ML dependencies."""
    if dim <= 0:
        return []
    vec = [0.0] * dim
    tokens = text.lower().split()
    for idx, token in enumerate(tokens):
        digest = hashlib.sha256(f"{idx}:{token}".encode("utf-8")).digest()
        for j in range(0, len(digest), 2):
            bucket = digest[j] % dim
            val = ((digest[j + 1] / 255.0) * 2.0) - 1.0
            vec[bucket] += val
    norm = math.sqrt(sum(v * v for v in vec))
    if norm == 0.0:
        return vec
    return [v / norm for v in vec]


class SimpleEmbeddingFunction:
    """Chroma-compatible embedding function fallback."""

    def __init__(self, dim: int = 128) -> None:
        self.dim = dim

    def __call__(self, input: list[str]) -> list[list[float]]:
        return [deterministic_embedding(text, dim=self.dim) for text in input]

    def name(self) -> str:
        """Return embedding function name expected by Chroma interface."""
        # Returning "default" avoids persisted-config conflicts when reopening
        # collections created with the default embedding function.
        return "default"

    def get_config(self) -> dict[str, int]:
        """Return serializable config expected by Chroma interface."""
        return {"dim": self.dim}

    @classmethod
    def build_from_config(cls, config: dict[str, int]) -> "SimpleEmbeddingFunction":
        """Construct embedding function from persisted Chroma config."""
        return cls(dim=int(config.get("dim", 128)))
