from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from sqlalchemy import and_, or_
from datetime import date

from app.core.dependencies import get_db, get_current_active_user
from app.models.user import User
from app.models.task import Task, TaskStatus, TaskPriority
from app.schemas import (
    TaskCreate, TaskUpdate, TaskStatusUpdate,
    TaskPositionUpdate, TaskResponse, MessageResponse,
)

router = APIRouter(prefix="/tasks", tags=["Görevler"])


def get_task_or_404(task_id: int, user_id: int, db: Session) -> Task:
    task = db.query(Task).filter(
        Task.id == task_id,
        Task.user_id == user_id,
        Task.is_deleted == False
    ).first()
    if not task:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Görev bulunamadı.")
    return task


@router.get("", response_model=List[TaskResponse])
def list_tasks(
    status: Optional[str] = Query(None, description="Durum filtresi"),
    priority: Optional[str] = Query(None, description="Öncelik filtresi"),
    project_id: Optional[int] = Query(None),
    category: Optional[str] = Query(None),
    search: Optional[str] = Query(None, description="Başlık veya açıklama ara"),
    due_before: Optional[date] = Query(None),
    due_after: Optional[date] = Query(None),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Görev listesi — filtreleme ve arama desteğiyle."""
    q = db.query(Task).filter(Task.user_id == current_user.id, Task.is_deleted == False)

    if status:
        q = q.filter(Task.status == status)
    if priority:
        q = q.filter(Task.priority == priority)
    if project_id is not None:
        q = q.filter(Task.project_id == project_id)
    if category:
        q = q.filter(Task.category == category)
    if search:
        q = q.filter(
            or_(Task.title.ilike(f"%{search}%"), Task.description.ilike(f"%{search}%"))
        )
    if due_before:
        q = q.filter(Task.due_date <= due_before)
    if due_after:
        q = q.filter(Task.due_date >= due_after)

    return q.order_by(Task.position.asc(), Task.created_at.desc()).all()


@router.post("", response_model=TaskResponse, status_code=status.HTTP_201_CREATED)
def create_task(
    task_in: TaskCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Yeni görev oluştur."""
    # Aynı status'ta en yüksek pozisyonu bul
    max_pos = db.query(Task).filter(
        Task.user_id == current_user.id,
        Task.status == task_in.status,
        Task.is_deleted == False,
    ).count()

    task = Task(
        **task_in.model_dump(),
        user_id=current_user.id,
        position=max_pos,
    )
    db.add(task)
    db.commit()
    db.refresh(task)
    return task


@router.get("/calendar", response_model=List[TaskResponse])
def get_tasks_for_calendar(
    start: date = Query(..., description="Başlangıç tarihi"),
    end: date = Query(..., description="Bitiş tarihi"),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Takvim görünümü için belirli tarih aralığındaki görevleri döner."""
    return db.query(Task).filter(
        Task.user_id == current_user.id,
        Task.is_deleted == False,
        Task.due_date >= start,
        Task.due_date <= end,
    ).all()


@router.get("/{task_id}", response_model=TaskResponse)
def get_task(
    task_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Görev detayı."""
    return get_task_or_404(task_id, current_user.id, db)


@router.put("/{task_id}", response_model=TaskResponse)
def update_task(
    task_id: int,
    task_in: TaskUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Görevi tamamen güncelle."""
    task = get_task_or_404(task_id, current_user.id, db)
    update_data = task_in.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(task, field, value)
    db.commit()
    db.refresh(task)
    return task


@router.delete("/{task_id}", response_model=MessageResponse)
def delete_task(
    task_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Görevi sil (soft delete)."""
    task = get_task_or_404(task_id, current_user.id, db)
    task.is_deleted = True
    db.commit()
    return MessageResponse(message="Görev silindi.")


@router.patch("/{task_id}/status", response_model=TaskResponse)
def update_task_status(
    task_id: int,
    status_in: TaskStatusUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Hızlı durum güncelleme."""
    task = get_task_or_404(task_id, current_user.id, db)
    task.status = status_in.status
    db.commit()
    db.refresh(task)
    return task


@router.patch("/{task_id}/position", response_model=TaskResponse)
def update_task_position(
    task_id: int,
    pos_in: TaskPositionUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_active_user),
):
    """Kanban sürükle-bırak pozisyon güncelleme."""
    task = get_task_or_404(task_id, current_user.id, db)
    task.position = pos_in.position
    if pos_in.status:
        task.status = pos_in.status
    db.commit()
    db.refresh(task)
    return task
