from fastapi import APIRouter, Depends, Query, status, Path
from sqlalchemy.orm import Session
from typing import Optional
from utils.utils import get_db, UserRole
from . import handler
from .schema import (
    UserCreate,
    UserUpdate,
    UserResponse,
    UserDetailResponse,
    NotificationCreate,
    NotificationUpdate,
    NotificationResponse,
    PaginatedResponse,
)

router = APIRouter(prefix="/users", tags=["Users"])


@router.post(
    "/",
    response_model=UserResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create User",
    description="Creates a new user account with email, password, role, and optional department assignment. Returns 409 if email already exists. Password must be minimum 8 characters including uppercase, lowercase, and number.",
)
def create_user_route(data: UserCreate, db: Session = Depends(get_db)):
    return handler.create_user(db, data)


@router.get(
    "/",
    response_model=PaginatedResponse[UserResponse],
    summary="List Users",
    description="Returns a paginated list of users. Supports optional filters for role, is_active status, department_id, and search by name or email.",
)
def list_users_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    role: Optional[UserRole] = Query(None),
    is_active: Optional[bool] = Query(None),
    department_id: Optional[str] = Query(None),
    search: Optional[str] = Query(None),
    db: Session = Depends(get_db),
):
    return handler.list_users(db, limit, offset, role, is_active, department_id, search)


@router.get(
    "/{user_id}",
    response_model=UserResponse,
    summary="Get User By ID",
    description="Returns user details by ID. Returns 404 if user not found.",
)
def get_user_route(user_id: str = Path(...), db: Session = Depends(get_db)):
    return handler.get_user_by_id(db, user_id)


@router.get(
    "/{user_id}/details",
    response_model=UserDetailResponse,
    summary="Get User Details",
    description="Returns comprehensive user details including department and team memberships. Returns 404 if user not found.",
)
def get_user_details_route(user_id: str = Path(...), db: Session = Depends(get_db)):
    return handler.get_user_details(db, user_id)


@router.put(
    "/{user_id}",
    response_model=UserResponse,
    summary="Update User",
    description="Updates user information. All fields are optional. Returns 404 if user not found, 409 if new email already exists for another user.",
)
def update_user_route(
    user_id: str = Path(...),
    data: UserUpdate = ...,
    db: Session = Depends(get_db),
):
    return handler.update_user(db, user_id, data)


@router.delete(
    "/{user_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete User",
    description="Deletes user by ID. Returns 404 if user not found, 409 if user is referenced by jobs or other resources.",
)
def delete_user_route(user_id: str = Path(...), db: Session = Depends(get_db)):
    return handler.delete_user(db, user_id)


# Notification routes
notification_router = APIRouter(prefix="/notifications", tags=["Notifications"])


@notification_router.post(
    "/",
    response_model=NotificationResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Notification",
    description="Creates a new notification for a user. Returns 400 if referenced user does not exist.",
)
def create_notification_route(data: NotificationCreate, db: Session = Depends(get_db)):
    return handler.create_notification(db, data)


@notification_router.get(
    "/",
    response_model=PaginatedResponse[NotificationResponse],
    summary="List Notifications",
    description="Returns a paginated list of notifications. Supports optional filters for user_id, is_read status, and notification_type.",
)
def list_notifications_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = Query(None),
    is_read: Optional[bool] = Query(None),
    notification_type: Optional[str] = Query(None),
    db: Session = Depends(get_db),
):
    return handler.list_notifications(db, limit, offset, user_id, is_read, notification_type)


@notification_router.get(
    "/{notification_id}",
    response_model=NotificationResponse,
    summary="Get Notification By ID",
    description="Returns notification details by ID. Returns 404 if notification not found.",
)
def get_notification_route(
    notification_id: str = Path(...), db: Session = Depends(get_db)
):
    return handler.get_notification_by_id(db, notification_id)


@notification_router.put(
    "/{notification_id}",
    response_model=NotificationResponse,
    summary="Update Notification",
    description="Updates notification details. All fields are optional. Returns 404 if notification not found.",
)
def update_notification_route(
    notification_id: str = Path(...),
    data: NotificationUpdate = ...,
    db: Session = Depends(get_db),
):
    return handler.update_notification(db, notification_id, data)


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


@notification_router.post(
    "/{notification_id}/read",
    response_model=NotificationResponse,
    summary="Mark Notification As Read",
    description="Marks a notification as read and records the read timestamp. Returns 404 if notification not found.",
)
def mark_notification_read_route(
    notification_id: str = Path(...), db: Session = Depends(get_db)
):
    return handler.mark_notification_read(db, notification_id)


@notification_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. Returns count of updated notifications.",
)
def mark_all_notifications_read_route(
    user_id: str = Query(...), db: Session = Depends(get_db)
):
    return handler.mark_all_notifications_read(db, user_id)


router.include_router(notification_router)