from sqlalchemy.orm import Session
from models.notification_model import Notification
from uuid import UUID
from fastapi import HTTPException, status
from utils.logging import logger

def create_notification(db: Session, user_id: UUID, message: str, link: str = None):
    try:
        new_notification = Notification(
            user_id=user_id,
            message=message,
            link=link,
            is_read=False
        )
        db.add(new_notification)
        db.commit()
        db.refresh(new_notification)
        return new_notification
    except Exception as e:
        db.rollback()
        logger.error(f"Error creating notification: {str(e)}")
        # We don't raise here usually to prevent breaking the main transaction flow if notification fails, 
        # but since we commit, we should handle carefully or pass it down.
        # Actually it's better to just log and not raise to not break the ticket creation/comment.
        pass

def get_user_notifications(db: Session, user_id: UUID, limit: int = 50):
    try:
        notifications = db.query(Notification).filter(Notification.user_id == user_id).order_by(Notification.created_at.desc()).limit(limit).all()
        unread_count = db.query(Notification).filter(Notification.user_id == user_id, Notification.is_read == False).count()
        return {
            "notifications": notifications,
            "unread_count": unread_count
        }
    except Exception as e:
        logger.error(f"Error fetching notifications: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to fetch notifications: {str(e)}"
        )

def mark_notification_as_read(db: Session, notification_id: UUID, user_id: UUID):
    try:
        notification = db.query(Notification).filter(Notification.id == notification_id, Notification.user_id == user_id).first()
        if not notification:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Notification not found"
            )
        notification.is_read = True
        db.commit()
        db.refresh(notification)
        return notification
    except HTTPException as e:
        raise e
    except Exception as e:
        db.rollback()
        logger.error(f"Error marking notification as read: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to update notification: {str(e)}"
        )

def mark_all_as_read(db: Session, user_id: UUID):
    try:
        notifications = db.query(Notification).filter(Notification.user_id == user_id, Notification.is_read == False).all()
        for notification in notifications:
            notification.is_read = True
        db.commit()
        return {"message": "All notifications marked as read"}
    except Exception as e:
        db.rollback()
        logger.error(f"Error marking all notifications as read: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to update notifications: {str(e)}"
        )
