"""Data models for the Vaikora SDK."""
from datetime import datetime
from enum import Enum
from typing import Any, Optional
from uuid import UUID

from pydantic import BaseModel, Field


class AgentType(str, Enum):
    """Type of AI agent."""
    AUTONOMOUS = "autonomous"
    SEMI_AUTONOMOUS = "semi_autonomous"
    SUPERVISED = "supervised"


class AgentStatus(str, Enum):
    """Status of an agent."""
    ACTIVE = "active"
    INACTIVE = "inactive"
    SUSPENDED = "suspended"


class ActionStatus(str, Enum):
    """Status of an action."""
    PENDING = "pending"
    APPROVED = "approved"
    DENIED = "denied"
    EXECUTED = "executed"
    FAILED = "failed"


class AlertSeverity(str, Enum):
    """Severity level of an alert."""
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"


class AlertStatus(str, Enum):
    """Status of an alert."""
    OPEN = "open"
    ACKNOWLEDGED = "acknowledged"
    RESOLVED = "resolved"
    IGNORED = "ignored"


class Agent(BaseModel):
    """Represents an AI agent registered with Vaikora."""
    id: UUID
    organization_id: UUID
    name: str
    agent_type: AgentType
    status: AgentStatus
    capabilities: list[str] = Field(default_factory=list)
    metadata: dict[str, Any] = Field(default_factory=dict)
    last_active_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime


class AgentCreate(BaseModel):
    """Schema for creating an agent."""
    name: str
    agent_type: AgentType = AgentType.AUTONOMOUS
    capabilities: list[str] = Field(default_factory=list)
    metadata: dict[str, Any] = Field(default_factory=dict)


class AgentUpdate(BaseModel):
    """Schema for updating an agent."""
    name: Optional[str] = None
    agent_type: Optional[AgentType] = None
    status: Optional[AgentStatus] = None
    capabilities: Optional[list[str]] = None
    metadata: Optional[dict[str, Any]] = None


class Action(BaseModel):
    """Represents a logged action by an agent."""
    id: UUID
    agent_id: UUID
    organization_id: UUID
    action_type: str
    resource: Optional[str] = None
    payload: dict[str, Any] = Field(default_factory=dict)
    status: ActionStatus
    decision: Optional[str] = None
    denial_reason: Optional[str] = None
    policy_id: Optional[UUID] = None
    is_anomaly: bool = False
    anomaly_score: Optional[float] = None
    anomaly_reasons: list[str] = Field(default_factory=list)
    execution_time_ms: Optional[int] = None
    error_message: Optional[str] = None
    metadata: dict[str, Any] = Field(default_factory=dict)
    created_at: datetime


class ActionSubmit(BaseModel):
    """Schema for submitting an action for evaluation."""
    agent_id: UUID
    action_type: str
    resource: Optional[str] = None
    payload: dict[str, Any] = Field(default_factory=dict)
    metadata: dict[str, Any] = Field(default_factory=dict)


class ActionResult(BaseModel):
    """Result of submitting an action for evaluation."""
    action_id: UUID
    approved: bool
    status: ActionStatus
    denial_reason: Optional[str] = None
    policy_id: Optional[UUID] = None
    is_anomaly: bool = False
    anomaly_score: Optional[float] = None
    anomaly_reasons: list[str] = Field(default_factory=list)
    warnings: list[str] = Field(default_factory=list)


class ActionComplete(BaseModel):
    """Schema for completing/finalizing an action."""
    status: ActionStatus
    execution_time_ms: Optional[int] = None
    error_message: Optional[str] = None
    result_metadata: dict[str, Any] = Field(default_factory=dict)


class Policy(BaseModel):
    """Represents a security policy."""
    id: UUID
    organization_id: UUID
    name: str
    description: Optional[str] = None
    policy_type: str
    enabled: bool
    priority: int
    action_types: list[str] = Field(default_factory=list)
    resources: list[str] = Field(default_factory=list)
    rules: dict[str, Any] = Field(default_factory=dict)
    conditions: dict[str, Any] = Field(default_factory=dict)
    created_at: datetime
    updated_at: datetime


class Alert(BaseModel):
    """Represents a security alert."""
    id: UUID
    organization_id: UUID
    agent_id: UUID
    action_log_id: Optional[UUID] = None
    policy_id: Optional[UUID] = None
    severity: AlertSeverity
    alert_type: str
    title: str
    description: Optional[str] = None
    status: AlertStatus
    metadata: dict[str, Any] = Field(default_factory=dict)
    acknowledged_at: Optional[datetime] = None
    acknowledged_by: Optional[UUID] = None
    resolved_at: Optional[datetime] = None
    resolved_by: Optional[UUID] = None
    resolution_notes: Optional[str] = None
    created_at: datetime


class PaginatedList(BaseModel):
    """Generic paginated list response."""
    items: list[Any]
    total: int
    page: int
    page_size: int
    has_more: bool


# Data Validation Models


class DataQualityLevel(str, Enum):
    """Quality level of validated data."""
    EXCELLENT = "excellent"  # 90-100
    GOOD = "good"           # 75-89
    FAIR = "fair"           # 50-74
    POOR = "poor"           # 25-49
    CRITICAL = "critical"   # 0-24


class PIIType(str, Enum):
    """Types of personally identifiable information."""
    EMAIL = "email"
    PHONE = "phone"
    SSN = "ssn"
    CREDIT_CARD = "credit_card"
    IP_ADDRESS = "ip_address"
    DATE_OF_BIRTH = "date_of_birth"
    ADDRESS = "address"
    NAME = "name"


class AnomalyType(str, Enum):
    """Types of data anomalies."""
    OUTLIER = "outlier"
    MISSING_VALUE = "missing_value"
    DUPLICATE = "duplicate"
    FORMAT_ERROR = "format_error"
    TYPE_MISMATCH = "type_mismatch"
    RANGE_VIOLATION = "range_violation"


class ToxicityCategory(str, Enum):
    """Categories of toxic content."""
    PROFANITY = "profanity"
    HATE_SPEECH = "hate_speech"
    THREAT = "threat"
    HARASSMENT = "harassment"
    SPAM = "spam"


class PIIDetection(BaseModel):
    """Detected PII in data."""
    pii_type: PIIType
    field: str
    value_preview: str  # Masked value
    confidence: float
    start_pos: Optional[int] = None
    end_pos: Optional[int] = None


class AnomalyDetection(BaseModel):
    """Detected anomaly in data."""
    anomaly_type: AnomalyType
    field: Optional[str] = None
    description: str
    severity: float  # 0.0 - 1.0
    record_index: Optional[int] = None


class ToxicityDetection(BaseModel):
    """Detected toxic content."""
    category: ToxicityCategory
    field: str
    confidence: float
    snippet: Optional[str] = None


class CleaningAction(BaseModel):
    """Data cleaning action performed."""
    action: str
    field: Optional[str] = None
    records_affected: int
    description: str


class DataValidationRequest(BaseModel):
    """Request to validate data."""
    data: Any  # Can be dict, list, or string
    check_pii: bool = True
    check_anomalies: bool = True
    check_toxicity: bool = True
    auto_clean: bool = False
    anomaly_threshold: float = 0.1
    strict_mode: bool = False


class DataValidationResult(BaseModel):
    """Result of data validation."""
    is_valid: bool
    quality_score: float  # 0-100
    quality_level: DataQualityLevel
    
    # Counts
    total_records: int
    pii_count: int = 0
    anomaly_count: int = 0
    toxicity_count: int = 0
    
    # Detailed findings
    pii_detections: list[PIIDetection] = Field(default_factory=list)
    anomaly_detections: list[AnomalyDetection] = Field(default_factory=list)
    toxicity_detections: list[ToxicityDetection] = Field(default_factory=list)
    
    # Cleaning results (if auto_clean=True)
    cleaned_data: Optional[Any] = None
    cleaning_actions: list[CleaningAction] = Field(default_factory=list)
    
    # Metadata
    processing_time_ms: float = 0


class DataValidationBatchResult(BaseModel):
    """Result of batch data validation."""
    total: int
    passed: int
    failed: int
    results: list[DataValidationResult]
    overall_quality_score: float

