"""Task models for enhanced task management with Kafka integration."""

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


class TaskStatus(str, Enum):
    """Task status enumeration."""
    PENDING = "pending"
    QUEUED = "queued"
    PROCESSING = "processing"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"


class TaskPriority(str, Enum):
    """Task priority enumeration."""
    LOW = "low"
    NORMAL = "normal"
    HIGH = "high"
    URGENT = "urgent"


class TaskType(str, Enum):
    """Task type enumeration."""
    SCRAPE = "scrape"
    BULK_SCRAPE = "bulk_scrape"
    SCHEDULED_SCRAPE = "scheduled_scrape"
    ANALYTICS = "analytics"


class TaskStats(BaseModel):
    """Detailed task statistics."""
    task_id: str
    status: TaskStatus
    created_at: datetime
    started_at: Optional[datetime] = None
    completed_at: Optional[datetime] = None
    execution_time: Optional[float] = None
    total_results: int = 0
    successful_engines: List[str] = []
    failed_engines: List[str] = []
    engine_stats: Dict[str, Any] = {}
    error_count: int = 0
    retry_count: int = 0
    last_error: Optional[str] = None
    progress_percentage: float = 0.0
    memory_usage: Optional[float] = None
    cpu_usage: Optional[float] = None


class ScrapeTaskRequest(BaseModel):
    """Enhanced scrape task request."""
    query: str = Field(..., description="Search query to scrape")
    engines: List[str] = Field(default=["bing"], description="Search engines to use")
    max_results: int = Field(default=10, ge=1, le=100, description="Maximum results per engine")
    priority: TaskPriority = Field(default=TaskPriority.NORMAL, description="Task priority")
    callback_url: Optional[str] = Field(None, description="Webhook URL for task completion")
    user_id: Optional[str] = Field(None, description="User identifier")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
    timeout: int = Field(default=300, ge=30, le=3600, description="Task timeout in seconds")
    retry_count: int = Field(default=3, ge=0, le=10, description="Number of retries on failure")


class BulkScrapeTaskRequest(BaseModel):
    """Bulk scrape task request."""
    queries: List[str] = Field(..., description="List of search queries")
    engines: List[str] = Field(default=["bing"], description="Search engines to use")
    max_results: int = Field(default=10, ge=1, le=50, description="Maximum results per engine per query")
    priority: TaskPriority = Field(default=TaskPriority.NORMAL, description="Task priority")
    callback_url: Optional[str] = Field(None, description="Webhook URL for task completion")
    user_id: Optional[str] = Field(None, description="User identifier")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
    parallel_queries: int = Field(default=3, ge=1, le=10, description="Number of parallel queries")


class TaskResponse(BaseModel):
    """Task response model."""
    task_id: str
    status: TaskStatus
    message: str
    created_at: datetime
    estimated_completion: Optional[datetime] = None
    queue_position: Optional[int] = None


class TaskResult(BaseModel):
    """Task result model."""
    task_id: str
    status: TaskStatus
    query: str
    engines_used: List[str]
    total_results: int
    execution_time: float
    created_at: datetime
    completed_at: Optional[datetime] = None
    results: List[Dict[str, Any]] = []
    stats: TaskStats
    error: Optional[str] = None


class TaskListResponse(BaseModel):
    """Task list response model."""
    tasks: List[TaskStats]
    total_count: int
    page: int
    page_size: int
    has_more: bool


class QueueStats(BaseModel):
    """Queue statistics model."""
    total_tasks: int
    pending_tasks: int
    processing_tasks: int
    completed_tasks: int
    failed_tasks: int
    queue_size: int
    average_processing_time: float
    throughput_per_minute: float
    active_workers: int


class UserStats(BaseModel):
    """User statistics model."""
    user_id: str
    total_tasks: int
    completed_tasks: int
    failed_tasks: int
    total_results: int
    average_execution_time: float
    last_activity: datetime
    quota_used: int
    quota_remaining: int


def generate_task_id() -> str:
    """Generate a unique task ID."""
    return str(uuid.uuid4())


def create_task_stats(task_id: str, status: TaskStatus = TaskStatus.PENDING) -> TaskStats:
    """Create initial task statistics."""
    return TaskStats(
        task_id=task_id,
        status=status,
        created_at=datetime.utcnow(),
        engine_stats={}
    )
