"""
Task Repository

Provides data access operations for tasks using the BaseRepository pattern.
"""

from typing import Optional, List
from sqlmodel import Session
from src.models.entities import TaskDB
from src.repositories.base_repository import BaseRepository
from src.config.database import engine
import logging

logger = logging.getLogger(__name__)


class TaskRepository(BaseRepository[TaskDB]):
    """ Repository for Task entities.
    
    Inherits all CRUD operations from BaseRepository and adds task-specific queries.
    """
    
    def __init__(self, session: Optional[Session] = None):
        """ Initialize TaskRepository.
        
        Args:
            session: Optional database session. If not provided, creates sessions per operation.
        """
        if session:
            super().__init__(TaskDB, session)
        else:
            # Create a temporary session for initialization
            with Session(engine) as temp_session:
                super().__init__(TaskDB, temp_session)
    
    def get_by_provider_task_id(self, provider_task_id: str) -> Optional[TaskDB]:
        """ Get a task by provider task ID.
        
        Args:
            provider_task_id: The task ID from the AI provider
            
        Returns:
            Task instance or None
        """ 
        return self.get_by_field("provider_task_id", provider_task_id)
    
    def list_by_status(
        self,
        status: str,
        limit: int = 100,
        offset: int = 0
    ) -> List[TaskDB]:
        """ List tasks by status.
        
        Args:
            status: Task status to filter by
            limit: Maximum number of tasks to return
            offset: Number of tasks to skip
            
        Returns:
            List of tasks
        """ 
        return self.list(
            skip=offset,
            limit=limit,
            filters={"status": status, "deleted_at": None},
            sort_by="created_at",
            sort_order="desc"
        )
    
    def list_by_user(
        self,
        user_id: str,
        limit: int = 100,
        offset: int = 0
    ) -> List[TaskDB]:
        """ List tasks for a specific user.
        
        Args:
            user_id: User ID to filter by
            limit: Maximum number of tasks to return
            offset: Number of tasks to skip
            
        Returns:
            List of tasks
        """ 
        return self.list(
            skip=offset,
            limit=limit,
            filters={"user_id": user_id, "deleted_at": None},
            sort_by="created_at",
            sort_order="desc"
        )
    
    def list_by_project(
        self,
        project_id: str,
        limit: int = 100,
        offset: int = 0
    ) -> List[TaskDB]:
        """ List tasks for a specific project.
        
        Args:
            project_id: Project ID to filter by
            limit: Maximum number of tasks to return
            offset: Number of tasks to skip
            
        Returns:
            List of tasks
        """ 
        return self.list(
            skip=offset,
            limit=limit,
            filters={"project_id": project_id, "deleted_at": None},
            sort_by="created_at",
            sort_order="desc"
        )
    
    def list_pending_tasks(self, limit: int = 100) -> List[TaskDB]:
        """ List all pending tasks.
        
        Args:
            limit: Maximum number of tasks to return
            
        Returns:
            List of pending tasks
        """ 
        return self.list(
            limit=limit,
            filters={"status": "pending", "deleted_at": None},
            sort_by="created_at",
            sort_order="asc"
        )
    
    def list_stuck_tasks(self, timeout_seconds: int = 3600) -> List[TaskDB]:
        """ List tasks that are stuck in processing state.
        
        Args:
            timeout_seconds: Number of seconds before a task is considered stuck
            
        Returns:
            List of stuck tasks
        """
        from datetime import datetime
        cutoff_time = datetime.now().timestamp() - timeout_seconds
        
        return self.list(
            filters={
                "status__in": ["processing", "retrying"],
                "updated_at__lt": cutoff_time,
                "deleted_at": None
            },
            sort_by="updated_at",
            sort_order="asc"
        )
    
    def count_by_status(self, status: str) -> int:
        """ 计数 tasks by status.
        
        Args:
            status: Task status to count
            
        Returns:
            Number of tasks with the given status
        """ 
        return self.count(filters={"status": status, "deleted_at": None})
    
    def count_by_user(self, user_id: str) -> int:
        """ 计数 tasks for a specific user.
        
        Args:
            user_id: User ID to count tasks for
            
        Returns:
            Number of tasks for the user
        """ 
        return self.count(filters={"user_id": user_id, "deleted_at": None})
