"""
Base candidate class for tracking potential answers.
"""

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

from ..constraints.base_constraint import Constraint
from ..evidence.base_evidence import Evidence


@dataclass
class Candidate:
    """A potential answer with supporting evidence."""

    name: str
    evidence: Dict[str, Evidence] = field(default_factory=dict)
    score: float = 0.0
    metadata: Dict[str, Any] = field(default_factory=dict)

    def add_evidence(self, constraint_id: str, evidence: Evidence):
        """Add evidence for a constraint."""
        self.evidence[constraint_id] = evidence

    def calculate_score(self, constraints: List[Constraint]) -> float:
        """Calculate overall score based on evidence and constraints."""
        if not constraints:
            return 0.0

        total_score = 0.0
        total_weight = 0.0

        for constraint in constraints:
            evidence = self.evidence.get(constraint.id)
            if evidence:
                score = evidence.confidence * constraint.weight
                total_score += score
            total_weight += constraint.weight

        self.score = total_score / total_weight if total_weight > 0 else 0.0
        return self.score

    def get_unverified_constraints(
        self, constraints: List[Constraint]
    ) -> List[Constraint]:
        """Get constraints that don't have evidence yet."""
        unverified = []
        for constraint in constraints:
            if constraint.id not in self.evidence:
                unverified.append(constraint)
        return unverified

    def get_weak_evidence(self, threshold: float = 0.5) -> List[str]:
        """Get constraint IDs with weak evidence."""
        weak = []
        for constraint_id, evidence in self.evidence.items():
            if evidence.confidence < threshold:
                weak.append(constraint_id)
        return weak
