"""Mapper for converting between TaskDB entity and Task schemas"""
import uuid
from datetime import datetime
from typing import Optional

from src.models.entities import TaskDB
from src.models.schemas import Task


class TaskMapper:
    """Mapper for Task entity and schemas"""
    
    @staticmethod
    def to_schema(db: TaskDB) -> Task:
        """Convert TaskDB entity to Task schema
        
        Args:
            db: TaskDB entity from database
            
        Returns:
            Task schema for API response
        """
        return Task(
            id=db.id,
            type=db.type,
            status=db.status,
            created_at=db.created_at,
            updated_at=db.updated_at,
            model=db.model or "",
            params=db.params or {},
            provider_task_id=db.provider_task_id,
            result=db.result,
            error=db.error,
            retry_count=db.retry_count,
            max_retries=db.max_retries,
            started_at=db.started_at,
            completed_at=db.completed_at,
            user_id=db.user_id,
            project_id=db.project_id,
            deleted_at=db.deleted_at,
        )
    
    @staticmethod
    def to_entity(
        task_type: str,
        model: str,
        params: dict,
        status: str = "pending",
        task_id: Optional[str] = None,
        user_id: Optional[str] = None,
        project_id: Optional[str] = None,
        max_retries: int = 3
    ) -> TaskDB:
        """ Create TaskDB entity from task parameters
        
        Args:
            task_type: Type of task (image, video, script, etc.)
            model: Model identifier
            params: Task parameters
            status: Initial task status
            task_id: Optional task ID (generated if not provided)
            user_id: Optional user ID for tracking
            project_id: Optional project ID for tracking
            max_retries: Maximum number of retries
            
        Returns:
            TaskDB entity for database storage
        """
        now = datetime.now().timestamp()
        
        return TaskDB(
            id=task_id or str(uuid.uuid4()),
            type=task_type,
            status=status,
            created_at=now,
            updated_at=now,
            model=model,
            params=params,
            retry_count=0,
            max_retries=max_retries,
            user_id=user_id,
            project_id=project_id,
        )
    
    @staticmethod
    def update_status(
        db: TaskDB,
        status: str,
        result: Optional[dict] = None,
        error: Optional[str] = None,
        provider_task_id: Optional[str] = None
    ) -> TaskDB:
        """Update task status and related fields
        
        Args:
            db: Existing TaskDB entity
            status: New task status
            result: Optional task result
            error: Optional error message
            provider_task_id: Optional provider task ID
            
        Returns:
            Updated TaskDB entity
        """
        db.status = status
        db.updated_at = datetime.now().timestamp()
        
        if result is not None:
            db.result = result
        
        if error is not None:
            db.error = error
        
        if provider_task_id is not None:
            db.provider_task_id = provider_task_id
        
        # Update lifecycle timestamps
        if status == "processing" and db.started_at is None:
            db.started_at = datetime.now().timestamp()
        
        if status in ["success", "failed", "timeout", "cancelled"]:
            db.completed_at = datetime.now().timestamp()
        
        return db
    
    @staticmethod
    def increment_retry(db: TaskDB) -> TaskDB:
        """Increment retry count for a task
        
        Args:
            db: Existing TaskDB entity
            
        Returns:
            Updated TaskDB entity
        """
        db.retry_count += 1
        db.updated_at = datetime.now().timestamp()
        return db
