"""
Data models for the Agent Trust SDK.
"""

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Optional


class Verdict(str, Enum):
    """Verification verdict."""
    ALLOW = "allow"
    CAUTION = "caution"
    BLOCK = "block"


class ThreatLevel(str, Enum):
    """Threat severity level."""
    SAFE = "safe"
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"


class InteractionOutcome(str, Enum):
    """Outcome of an agent interaction."""
    SUCCESS = "success"
    FAILURE = "failure"
    NEUTRAL = "neutral"


@dataclass
class ThreatMatch:
    """A detected threat pattern."""
    pattern_id: str
    pattern_name: str
    severity: ThreatLevel
    location: str
    matched_text: Optional[str] = None
    description: Optional[str] = None


@dataclass
class VerificationResult:
    """Result of verifying an agent or message."""
    request_id: str
    verdict: Verdict
    threat_level: ThreatLevel
    threats: list[ThreatMatch] = field(default_factory=list)
    reasoning: str = ""
    trust_score: Optional[float] = None
    checked_at: Optional[datetime] = None
    
    # Agent-specific fields
    agent_url: Optional[str] = None
    agent_name: Optional[str] = None
    is_registered: bool = False
    is_verified: bool = False
    reputation_score: Optional[float] = None
    
    @property
    def is_safe(self) -> bool:
        """Returns True if the verdict is allow."""
        return self.verdict == Verdict.ALLOW
    
    @property
    def is_blocked(self) -> bool:
        """Returns True if the verdict is block."""
        return self.verdict == Verdict.BLOCK
    
    @property
    def has_threats(self) -> bool:
        """Returns True if any threats were detected."""
        return len(self.threats) > 0


@dataclass
class ScoreBreakdown:
    """Detailed breakdown of trust score calculation."""
    base_score: float
    interaction_score: float
    report_penalty: float
    verification_bonus: float
    time_decay: float
    final_score: float
    total_interactions: int = 0
    success_rate: Optional[float] = None
    days_since_last_interaction: Optional[int] = None


@dataclass
class AgentReputation:
    """Agent reputation details."""
    agent_url: str
    trust_score: float
    is_registered: bool
    is_verified: bool
    agent_name: Optional[str] = None
    first_seen: Optional[datetime] = None
    last_seen: Optional[datetime] = None
    total_interactions: int = 0
    successful_interactions: int = 0
    failed_interactions: int = 0
    reports_against: int = 0
    score_breakdown: Optional[dict] = None
    
    @property
    def success_rate(self) -> Optional[float]:
        """Calculate success rate from interactions."""
        if self.total_interactions == 0:
            return None
        return self.successful_interactions / self.total_interactions
    
    @property
    def is_trusted(self) -> bool:
        """Returns True if trust score >= 70."""
        return self.trust_score >= 70
    
    @property
    def is_suspicious(self) -> bool:
        """Returns True if trust score < 30."""
        return self.trust_score < 30


@dataclass
class InteractionResult:
    """Result of reporting an interaction."""
    interaction_id: str
    agent_url: str
    outcome: InteractionOutcome
    score_delta: float
    new_trust_score: float
    message: str
    created_at: Optional[datetime] = None


@dataclass 
class TextScanResult:
    """Result of scanning raw text."""
    request_id: str
    verdict: Verdict
    threat_level: ThreatLevel
    threats: list[ThreatMatch] = field(default_factory=list)
    reasoning: str = ""
    text_length: int = 0
    scan_time_ms: float = 0.0
    
    @property
    def is_safe(self) -> bool:
        return self.verdict == Verdict.ALLOW


# ============================================================================
# Guard Models (for TrustGuard)
# ============================================================================

class ContentSource(str, Enum):
    """Source type for scanned content."""
    WEB = "web"
    DOCUMENT = "document"
    EMAIL = "email"
    TOOL = "tool"
    MEMORY = "memory"
    RAG = "rag"
    UNKNOWN = "unknown"


@dataclass
class GuardResult:
    """Result of content guard scan."""
    safe: bool
    verdict: Verdict
    threat_level: ThreatLevel
    threats: list[ThreatMatch] = field(default_factory=list)
    reasoning: str = ""
    source_type: ContentSource = ContentSource.UNKNOWN
    content_length: int = 0
    scan_time_ms: float = 0.0
    request_id: str = ""
    checked_at: Optional[datetime] = None
    sanitized_content: Optional[str] = None
    
    @property
    def is_safe(self) -> bool:
        """Returns True if content is safe to process."""
        return self.safe
    
    @property
    def is_blocked(self) -> bool:
        """Returns True if verdict is block."""
        return self.verdict == Verdict.BLOCK
    
    @property
    def has_threats(self) -> bool:
        """Returns True if any threats were detected."""
        return len(self.threats) > 0


@dataclass
class BatchScanItem:
    """Single item for batch scanning."""
    id: str
    source_type: ContentSource
    content: str
    metadata: Optional[dict] = None


@dataclass
class BatchScanResult:
    """Result for a single item in batch scan."""
    id: str
    result: GuardResult


@dataclass
class BatchScanResponse:
    """Response for batch scan operation."""
    total: int
    safe_count: int
    threat_count: int
    results: list[BatchScanResult] = field(default_factory=list)
    scan_time_ms: float = 0.0
    
    @property
    def all_safe(self) -> bool:
        """Returns True if all items are safe."""
        return self.threat_count == 0


@dataclass
class FetchAndScanResult:
    """Result of fetching and scanning a URL."""
    url: str
    fetched: bool
    fetch_error: Optional[str] = None
    content_length: Optional[int] = None
    content_type: Optional[str] = None
    guard_result: Optional[GuardResult] = None
    
    @property
    def is_safe(self) -> bool:
        """Returns True if fetch succeeded and content is safe."""
        return self.fetched and self.guard_result is not None and self.guard_result.safe
