"""Lightweight clustering utilities for memory consolidation."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any

try:
    import numpy as np
except Exception:  # pragma: no cover
    np = None  # type: ignore


@dataclass
class Cluster:
    indices: list[int]
    centroid: Any


def threshold_cluster(
    embeddings: Any,
    threshold: float = 0.6,
    min_cluster_size: int = 3,
) -> list[Cluster]:
    """Group vectors by cosine similarity threshold (agglomerative-lite)."""
    if np is None:
        return []
    if embeddings.ndim != 2 or embeddings.shape[0] < min_cluster_size:
        return []

    norms = np.linalg.norm(embeddings, axis=1, keepdims=True)
    normalized = embeddings / (norms + 1e-8)
    similarity = normalized @ normalized.T

    clusters: list[Cluster] = []
    assigned = set()

    for i in range(len(embeddings)):
        if i in assigned:
            continue
        current = [i]
        assigned.add(i)

        for j in range(i + 1, len(embeddings)):
            if j in assigned:
                continue
            if similarity[i][j] >= threshold:
                current.append(j)
                assigned.add(j)

        if len(current) >= min_cluster_size:
            centroid = np.mean(embeddings[current], axis=0)
            clusters.append(Cluster(indices=current, centroid=centroid))

    return clusters
