from __future__ import annotations

from dataclasses import asdict, dataclass, field
from typing import Any, Dict, List, Optional


@dataclass
class CodeFunctionEvidence:
    node_id: str
    name: str
    qualified_name: str
    file: str
    start_line: Optional[int] = None
    end_line: Optional[int] = None
    signature: str = ""
    summary: str = ""
    logic_flow: str = ""
    code_snippet: str = ""
    calls: List[str] = field(default_factory=list)
    called_by: List[str] = field(default_factory=list)
    includes: List[str] = field(default_factory=list)
    embedding_model: str = ""
    embedding_dim: int = 0
    embedding_available: bool = True
    raw: Dict[str, Any] = field(default_factory=dict)

    def to_dict(self) -> Dict[str, Any]:
        return asdict(self)


@dataclass
class CodeSearchHit:
    evidence: CodeFunctionEvidence
    similarity: float
    distance: float
    rank: int

    def to_dict(self) -> Dict[str, Any]:
        data = self.evidence.to_dict()
        data.update(
            {
                "similarity": self.similarity,
                "distance": self.distance,
                "rank": self.rank,
            }
        )
        return data


@dataclass
class CodeGraphContext:
    node_id: str
    callers: List[CodeFunctionEvidence] = field(default_factory=list)
    callees: List[CodeFunctionEvidence] = field(default_factory=list)
    call_chains: List[str] = field(default_factory=list)

    def to_dict(self) -> Dict[str, Any]:
        return {
            "node_id": self.node_id,
            "callers": [item.to_dict() for item in self.callers],
            "callees": [item.to_dict() for item in self.callees],
            "call_chains": self.call_chains,
        }
