"""Cosine similarity — numpy. RAG retriever çekirdeği. Saf fonksiyon."""
import numpy as np


def cosine_similarity(a: list[float], b: list[float]) -> float:
    va = np.asarray(a, dtype=np.float32)
    vb = np.asarray(b, dtype=np.float32)
    denom = float(np.linalg.norm(va) * np.linalg.norm(vb)) + 1e-10
    return float(np.dot(va, vb) / denom)


def top_k_by_cosine(
    query_vec: list[float],
    candidates: list[tuple[str, list[float]]],
    k: int = 5,
) -> list[tuple[str, float]]:
    """candidates: (id, embedding) listesi → en yüksek skorlu k tane (id, score)."""
    if not query_vec or not candidates:
        return []
    q = np.asarray(query_vec, dtype=np.float32)
    q_norm = float(np.linalg.norm(q)) + 1e-10

    scored: list[tuple[str, float]] = []
    for cid, emb in candidates:
        if not emb:
            continue
        v = np.asarray(emb, dtype=np.float32)
        score = float(np.dot(q, v) / (q_norm * float(np.linalg.norm(v)) + 1e-10))
        scored.append((cid, score))

    scored.sort(key=lambda x: x[1], reverse=True)
    return scored[:k]
