from typing import List
import math

from analogai.foundation.common.utils.similarity.similarity_service import SimilarityService
from analogai.foundation.infrastructure.services.embedding_service import EmbeddingService


class EmbeddingSimilarityService(SimilarityService):
    def __init__(self, embedding_service: EmbeddingService | None = None):
        self._embedding_service = embedding_service or EmbeddingService()

    def similarity(self, text_a: str, text_b: str) -> float:
        vector_a = self._embedding_service.encode(text_a)
        vector_b = self._embedding_service.encode(text_b)
        return self._cosine_similarity(vector_a, vector_b)

    @staticmethod
    def _cosine_similarity(vector_a: List[float], vector_b: List[float]) -> float:
        if not vector_a or not vector_b or len(vector_a) != len(vector_b):
            return 0.0
        dot = sum(a * b for a, b in zip(vector_a, vector_b))
        norm_a = math.sqrt(sum(a * a for a in vector_a))
        norm_b = math.sqrt(sum(b * b for b in vector_b))
        if norm_a == 0 or norm_b == 0:
            return 0.0
        return dot / (norm_a * norm_b)
