"""Task business logic."""

from typing import List, Optional
from datetime import datetime, timezone
from sqlalchemy.orm import Session
from app.models.task import Task, TaskStatus
from app.schemas.task import TaskCreate, TaskUpdate


class TaskService:
    """Service for task operations."""

    def __init__(self, db: Session):
        self.db = db

    def get_all(self, owner_id: int, skip: int = 0, limit: int = 100) -> tuple[List[Task], int]:
        """Get all tasks for a user with pagination."""
        query = self.db.query(Task).filter(Task.owner_id == owner_id)
        total = query.count()
        tasks = query.order_by(Task.created_at.desc()).offset(skip).limit(limit).all()
        return tasks, total

    def get_by_id(self, task_id: int, owner_id: int) -> Optional[Task]:
        """Get a task by ID for a specific user."""
        return self.db.query(Task).filter(
            Task.id == task_id,
            Task.owner_id == owner_id
        ).first()

    def create(self, task_data: TaskCreate, owner_id: int) -> Task:
        """Create a new task."""
        task = Task(
            title=task_data.title,
            description=task_data.description,
            priority=task_data.priority.value,
            due_date=task_data.due_date,
            owner_id=owner_id,
        )
        self.db.add(task)
        self.db.commit()
        self.db.refresh(task)
        return task

    def update(self, task_id: int, owner_id: int, task_data: TaskUpdate) -> Optional[Task]:
        """Update a task."""
        task = self.get_by_id(task_id, owner_id)
        if not task:
            return None

        update_data = task_data.model_dump(exclude_unset=True)

        # Handle status changes
        if "status" in update_data:
            update_data["status"] = update_data["status"].value
            if update_data["status"] == TaskStatus.COMPLETED.value:
                update_data["completed_at"] = datetime.now(timezone.utc)

        # Handle priority changes
        if "priority" in update_data:
            update_data["priority"] = update_data["priority"].value

        for key, value in update_data.items():
            setattr(task, key, value)

        self.db.commit()
        self.db.refresh(task)
        return task

    def delete(self, task_id: int, owner_id: int) -> bool:
        """Delete a task."""
        task = self.get_by_id(task_id, owner_id)
        if not task:
            return False
        self.db.delete(task)
        self.db.commit()
        return True

    def get_by_status(self, owner_id: int, status: TaskStatus) -> List[Task]:
        """Get tasks by status."""
        return self.db.query(Task).filter(
            Task.owner_id == owner_id,
            Task.status == status.value
        ).all()
