from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session

from .db import get_db
from .schemas import (
    TaskCreate,
    TaskUpdate,
    TaskResponse,
    RescheduleRequest,
    HealthResponse,
)
from .services import TaskService
from .auth.dependencies import get_current_user
from .auth.models import User

router = APIRouter()


def get_task_service(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> TaskService:
    return TaskService(db, current_user.id)


@router.get("/health", response_model=HealthResponse)
def health_check():
    return HealthResponse()


@router.get("/tasks", response_model=list[TaskResponse])
def get_tasks(
    date: str = Query(..., pattern=r"^\d{4}-\d{2}-\d{2}$"),
    status: Optional[str] = Query(None, pattern="^(all|active|done)$"),
    service: TaskService = Depends(get_task_service),
):
    tasks = service.get_tasks_by_date(date, status)
    return tasks


@router.get("/tasks/{task_id}", response_model=TaskResponse)
def get_task(
    task_id: str,
    service: TaskService = Depends(get_task_service),
):
    task = service.get_task_by_id(task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    return task


@router.post("/tasks", response_model=TaskResponse, status_code=201)
def create_task(
    task_data: TaskCreate,
    service: TaskService = Depends(get_task_service),
):
    task = service.create_task(task_data)
    return task


@router.put("/tasks/{task_id}", response_model=TaskResponse)
def update_task(
    task_id: str,
    task_data: TaskUpdate,
    service: TaskService = Depends(get_task_service),
):
    task = service.update_task(task_id, task_data)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    return task


@router.delete("/tasks/{task_id}", status_code=204)
def delete_task(
    task_id: str,
    service: TaskService = Depends(get_task_service),
):
    deleted = service.delete_task(task_id)
    if not deleted:
        raise HTTPException(status_code=404, detail="Task not found")
    return None


@router.patch("/tasks/{task_id}/toggle", response_model=TaskResponse)
def toggle_task_status(
    task_id: str,
    service: TaskService = Depends(get_task_service),
):
    task = service.toggle_task_status(task_id)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    return task


@router.post("/tasks/{task_id}/reschedule", response_model=TaskResponse)
def reschedule_task(
    task_id: str,
    request: RescheduleRequest,
    service: TaskService = Depends(get_task_service),
):
    task = service.reschedule_task(task_id, request.target_date)
    if not task:
        raise HTTPException(status_code=404, detail="Task not found")
    return task
