from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional, List
from utils.utils import get_db
from . import handler
from .schema import NotificationCreate, NotificationUpdate, NotificationResponse

router = APIRouter(prefix="/notifications", tags=["Notifications"])

@router.post(
    "/",
    response_model=NotificationResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Notification",
    description="Creates a new notification for a user. Validates that the user exists before creating the notification. Returns 404 if the user is not found.",
)
def create_notification_route(data: NotificationCreate, db: Session = Depends(get_db)):
    return handler.create_notification(db, data)

@router.get(
    "/",
    response_model=List[NotificationResponse],
    summary="List Notifications",
    description="Returns a paginated list of notifications. Supports optional filters for user_id, notification_type, is_read status, and delivery_status. Results are ordered by creation date descending.",
)
def list_notifications_route(
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = Query(None, min_length=36, max_length=36),
    notification_type: Optional[str] = None,
    is_read: Optional[bool] = None,
    delivery_status: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_notifications(db, limit, offset, user_id, notification_type, is_read, delivery_status)

@router.get(
    "/unread",
    response_model=List[NotificationResponse],
    summary="List Unread Notifications",
    description="Returns a paginated list of unread notifications for a specific user. Validates that the user exists. Returns 404 if the user is not found.",
)
def get_unread_notifications_route(
    user_id: str = Query(..., min_length=36, max_length=36),
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0),
    db: Session = Depends(get_db),
):
    return handler.get_unread_notifications(db, user_id, limit, offset)

@router.get(
    "/{notification_id}",
    response_model=NotificationResponse,
    summary="Get Notification",
    description="Returns a single notification by ID. Returns 404 if the notification is not found.",
)
def get_notification_route(notification_id: str, db: Session = Depends(get_db)):
    return handler.get_notification(db, notification_id)

@router.put(
    "/{notification_id}",
    response_model=NotificationResponse,
    summary="Update Notification",
    description="Updates an existing notification. All fields are optional. Validates that the user exists if user_id is being updated. Returns 404 if the notification or user is not found.",
)
def update_notification_route(
    notification_id: str,
    data: NotificationUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_notification(db, notification_id, data)

@router.delete(
    "/{notification_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Notification",
    description="Deletes a notification by ID. Returns 404 if the notification is not found.",
)
def delete_notification_route(notification_id: str, db: Session = Depends(get_db)):
    return handler.delete_notification(db, notification_id)

@router.post(
    "/{notification_id}/mark-read",
    response_model=NotificationResponse,
    summary="Mark Notification As Read",
    description="Marks a single notification as read and sets the read_at timestamp. If the notification is already read, returns it unchanged. Returns 404 if the notification is not found.",
)
def mark_notification_as_read_route(notification_id: str, db: Session = Depends(get_db)):
    return handler.mark_notification_as_read(db, notification_id)

@router.post(
    "/mark-all-read",
    status_code=status.HTTP_200_OK,
    summary="Mark All Notifications As Read",
    description="Marks all unread notifications for a specific user as read. Validates that the user exists. Returns the count of notifications marked as read. Returns 404 if the user is not found.",
)
def mark_all_as_read_route(
    user_id: str = Query(..., min_length=36, max_length=36),
    db: Session = Depends(get_db),
):
    return handler.mark_all_as_read(db, user_id)