from pydantic import BaseModel, Field
from typing import List, Dict, Optional, Literal
from datetime import datetime
import uuid

class SearchRequest(BaseModel):
    request_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    query: str
    search_engine: Optional[str] = None
    max_results: int = 10
    delay: int = 2
    timeout: int = 30
    headless: bool = True
    user_id: Optional[str] = None
    session_id: Optional[str] = None
    timestamp: datetime = Field(default_factory=datetime.now)

class SearchEngineRequest(BaseModel):
    request_id: str
    query: str
    max_results: int = 10
    delay: int = 2
    timeout: int = 30
    headless: bool = True
    timestamp: datetime = Field(default_factory=datetime.now)

class SearchResult(BaseModel):
    title: Optional[str] = None
    url: Optional[str] = None
    snippet: Optional[str] = None
    displayed_url: Optional[str] = None
    rank: Optional[int] = None

class SearchResponse(BaseModel):
    request_id: str
    search_engine: str
    query: str
    results: List[SearchResult]
    total_results: int
    timestamp: datetime = Field(default_factory=datetime.now)
    error: Optional[str] = None
    processing_time: Optional[float] = None

class MetadataRequest(BaseModel):
    request_id: str
    url: str
    timeout: int = 30
    timestamp: datetime = Field(default_factory=datetime.now)

class PageMetadata(BaseModel):
    url: str
    title: Optional[str] = None
    description: Optional[str] = None
    keywords: Optional[str] = None
    author: Optional[str] = None
    publish_date: Optional[str] = None
    last_modified: Optional[str] = None
    canonical_url: Optional[str] = None
    language: Optional[str] = None
    page_size: Optional[int] = None
    load_time: Optional[float] = None
    status_code: Optional[int] = None
    content_type: Optional[str] = None
    word_count: Optional[int] = None
    images_count: Optional[int] = None
    links_count: Optional[int] = None
    external_links_count: Optional[int] = None
    social_media_links: List[str] = []
    email_addresses: List[str] = []
    phone_numbers: List[str] = []
    error: Optional[str] = None

class MetadataResponse(BaseModel):
    request_id: str
    metadata: PageMetadata
    timestamp: datetime = Field(default_factory=datetime.now)
    processing_time: Optional[float] = None

class ExportRequest(BaseModel):
    request_id: str
    data: Dict
    format: Literal['json', 'csv', 'both'] = 'json'
    filename: Optional[str] = None
    timestamp: datetime = Field(default_factory=datetime.now)

class ExportResponse(BaseModel):
    request_id: str
    files: List[str]
    timestamp: datetime = Field(default_factory=datetime.now)
    error: Optional[str] = None

class BatchSearchRequest(BaseModel):
    request_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    queries: List[str]
    search_engines: List[str] = ['google']
    max_results: int = 10
    delay: int = 2
    export_format: Literal['json', 'csv', 'both'] = 'json'
    user_id: Optional[str] = None
    session_id: Optional[str] = None
    timestamp: datetime = Field(default_factory=datetime.now)

class ProcessingStatus(BaseModel):
    request_id: str
    status: Literal['pending', 'processing', 'completed', 'failed']
    progress: float = 0.0
    message: Optional[str] = None
    result_files: List[str] = []
    timestamp: datetime = Field(default_factory=datetime.now)

class HealthStatus(BaseModel):
    service_name: str
    status: Literal['healthy', 'unhealthy', 'degraded']
    timestamp: datetime = Field(default_factory=datetime.now)
    details: Optional[Dict] = None

class SystemInfo(BaseModel):
    system: str
    release: str
    version: str
    machine: str
    processor: str
    python_version: str

class ErrorResponse(BaseModel):
    error: str
    details: Optional[str] = None
    timestamp: datetime = Field(default_factory=datetime.now)
    request_id: Optional[str] = None
