"""
Error models and codes for the aphub ecosystem.
"""

from enum import Enum
from pydantic import BaseModel, Field
from typing import Optional, Dict, Any


class ErrorCode(str, Enum):
    """Standard error codes."""
    
    # General errors (1xxx)
    UNKNOWN_ERROR = "E1000"
    INTERNAL_ERROR = "E1001"
    INVALID_REQUEST = "E1002"
    VALIDATION_ERROR = "E1003"
    
    # Authentication errors (2xxx)
    UNAUTHORIZED = "E2000"
    INVALID_CREDENTIALS = "E2001"
    TOKEN_EXPIRED = "E2002"
    TOKEN_INVALID = "E2003"
    INSUFFICIENT_PERMISSIONS = "E2004"
    
    # Agent errors (3xxx)
    AGENT_NOT_FOUND = "E3000"
    AGENT_ALREADY_EXISTS = "E3001"
    AGENT_NAME_INVALID = "E3002"
    AGENT_ACCESS_DENIED = "E3003"
    
    # Version errors (4xxx)
    VERSION_NOT_FOUND = "E4000"
    VERSION_ALREADY_EXISTS = "E4001"
    VERSION_INVALID = "E4002"
    TAG_NOT_FOUND = "E4003"
    
    # Manifest errors (5xxx)
    MANIFEST_INVALID = "E5000"
    MANIFEST_MISSING_FIELD = "E5001"
    FRAMEWORK_NOT_SUPPORTED = "E5002"
    
    # Storage errors (6xxx)
    STORAGE_ERROR = "E6000"
    FILE_NOT_FOUND = "E6001"
    FILE_TOO_LARGE = "E6002"
    CHECKSUM_MISMATCH = "E6003"
    
    # Rate limiting (7xxx)
    RATE_LIMIT_EXCEEDED = "E7000"
    QUOTA_EXCEEDED = "E7001"


class HubError(BaseModel):
    """Standard error response format."""
    
    success: bool = Field(False, description="Always False for errors")
    error: str = Field(..., description="Error message")
    code: ErrorCode = Field(..., description="Error code")
    
    # Optional details
    details: Optional[Dict[str, Any]] = Field(None, description="Additional error details")
    field: Optional[str] = Field(None, description="Field that caused the error")
    
    # Request context
    request_id: Optional[str] = Field(None, description="Request ID for tracing")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "success": False,
                "error": "Agent not found",
                "code": "E3000",
                "details": {"name": "my-agent", "version": "1.0.0"},
                "request_id": "req_abc123"
            }
        }
    }


class ValidationErrorDetail(BaseModel):
    """Validation error detail."""
    
    field: str = Field(..., description="Field path")
    message: str = Field(..., description="Error message")
    value: Optional[Any] = Field(None, description="Invalid value")


class ValidationError(HubError):
    """Validation error with field details."""
    
    code: ErrorCode = Field(ErrorCode.VALIDATION_ERROR, description="Error code")
    errors: list[ValidationErrorDetail] = Field(
        default_factory=list, 
        description="Field validation errors"
    )
