from celery import shared_task, Celery
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
from utility.auth_token import get_current_user
from models.models import Notification, User
from database import get_db
from schemas.notifications import NotificationOut, NotificationUpdate
from pydantic import BaseModel
from core.config import settings


router = APIRouter()
celery = Celery(
    __name__,
    broker=settings.CELERY_BROKER_URL,
    backend=settings.CELERY_RESULT_BACKEND
)

# ===== SCHEMAS PYDANTIC =====
class NotificationUpdate(BaseModel):
    is_read: Optional[bool] = None

class BulkMarkReadRequest(BaseModel):
    notification_ids: List[str]


# ===== 1. LIRE TOUTES LES NOTIFICATIONS =====
@router.get("/financials/user/notifications")
async def get_notifications(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
    unread_only: bool = False
):
    """
    Récupère toutes les notifications de l'utilisateur connecté
    
    - unread_only: si True, ne retourne que les notifications non lues
    """
    query = db.query(Notification).filter(Notification.user_id == current_user.id)
    
    if unread_only:
        query = query.filter(Notification.is_read == False)
    
    notifications = query.order_by(Notification.created_at.desc()).all()
    
    json_data = jsonable_encoder(notifications)
    return JSONResponse(
        content=json_data,
        media_type="application/json; charset=utf-8"
    )

# ===== 2. LIRE UNE NOTIFICATION SPÉCIFIQUE =====
@router.get("/financials/user/notifications/{notification_id}")
async def get_notification(
    notification_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Récupère une notification spécifique"""
    notification = db.query(Notification).filter(
        Notification.id == notification_id,
        Notification.user_id == current_user.id
    ).first()
    
    if not notification:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Notification non trouvée"
        )
    
    json_data = jsonable_encoder(notification)
    return JSONResponse(
        content=json_data,
        media_type="application/json; charset=utf-8"
    )

# ===== 3. MARQUER UNE NOTIFICATION COMME LUE/NON LUE =====
@router.patch("/financials/user/notifications/{notification_id}")
async def update_notification_status(
    notification_id: str,
    update_data: NotificationUpdate,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    Marque une notification comme lue ou non lue
    
    Body: {"is_read": true}
    """
    notification = db.query(Notification).filter(
        Notification.id == notification_id,
        Notification.user_id == current_user.id
    ).first()
    
    if not notification:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Notification non trouvée"
        )
    
    # Mise à jour du statut
    if update_data.is_read is not None:
        notification.is_read = update_data.is_read
        notification.read_at = datetime.now() if update_data.is_read else None
    
    db.commit()
    db.refresh(notification)
    
    json_data = jsonable_encoder(notification)
    return JSONResponse(
        content=json_data,
        media_type="application/json; charset=utf-8"
    )

# ===== 4. MARQUER TOUTES LES NOTIFICATIONS COMME LUES =====
@router.post("/financials/user/notifications/mark-all-read")
async def mark_all_as_read(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Marque toutes les notifications de l'utilisateur comme lues"""
    updated_count = db.query(Notification).filter(
        Notification.user_id == current_user.id,
        Notification.is_read == False
    ).update({
        "is_read": True,
        "read_at": datetime.now()
    })
    
    db.commit()
    
    return JSONResponse(
        content={
            "message": f"{updated_count} notification(s) marquée(s) comme lue(s)",
            "count": updated_count
        },
        media_type="application/json; charset=utf-8"
    )

# ===== 5. MARQUER PLUSIEURS NOTIFICATIONS COMME LUES =====
@router.post("/financials/user/notifications/mark-read")
async def mark_notifications_as_read(
    request: BulkMarkReadRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    Marque plusieurs notifications comme lues
    
    Body: {"notification_ids": ["id1", "id2", "id3"]}
    """
    updated_count = db.query(Notification).filter(
        Notification.id.in_(request.notification_ids),
        Notification.user_id == current_user.id
    ).update({
        "is_read": True,
        "read_at": datetime.now()
    }, synchronize_session=False)
    
    db.commit()
    
    return JSONResponse(
        content={
            "message": f"{updated_count} notification(s) marquée(s) comme lue(s)",
            "count": updated_count
        },
        media_type="application/json; charset=utf-8"
    )

# ===== 6. SUPPRIMER UNE NOTIFICATION =====
@router.delete("/financials/user/notifications/{notification_id}")
async def delete_notification(
    notification_id: str,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Supprime une notification spécifique"""
    notification = db.query(Notification).filter(
        Notification.id == notification_id,
        Notification.user_id == current_user.id
    ).first()
    
    if not notification:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Notification non trouvée"
        )
    
    db.delete(notification)
    db.commit()
    
    return JSONResponse(
        content={"message": "Notification supprimée avec succès"},
        status_code=status.HTTP_200_OK
    )

# ===== 7. SUPPRIMER TOUTES LES NOTIFICATIONS LUES =====
@router.delete("/financials/user/notifications/delete-read")
async def delete_read_notifications(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Supprime toutes les notifications lues de l'utilisateur"""
    deleted_count = db.query(Notification).filter(
        Notification.user_id == current_user.id,
        Notification.is_read == True
    ).delete()
    
    db.commit()
    
    return JSONResponse(
        content={
            "message": f"{deleted_count} notification(s) supprimée(s)",
            "count": deleted_count
        },
        media_type="application/json; charset=utf-8"
    )

# ===== 8. SUPPRIMER TOUTES LES NOTIFICATIONS =====
@router.delete("/financials/user/notifications")
async def delete_all_notifications(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Supprime toutes les notifications de l'utilisateur"""
    deleted_count = db.query(Notification).filter(
        Notification.user_id == current_user.id
    ).delete()
    
    db.commit()
    
    return JSONResponse(
        content={
            "message": f"{deleted_count} notification(s) supprimée(s)",
            "count": deleted_count
        },
        media_type="application/json; charset=utf-8"
    )

# ===== 9. OBTENIR LE NOMBRE DE NOTIFICATIONS NON LUES =====
@router.get("/financials/user/notifications/unread/count")
async def get_unread_count(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """Retourne le nombre de notifications non lues"""
    count = db.query(Notification).filter(
        Notification.user_id == current_user.id,
        Notification.is_read == False
    ).count()
    
    return JSONResponse(
        content={"unread_count": count},
        media_type="application/json; charset=utf-8"
    )