from rest_framework.views import APIView 
from rest_framework import status
from .serializers import EmailNotificationSerializer,NotificationReceiverSerializer
from django.core.mail import send_mail  
from .serializers import AppNotificationSerializer, NotificationsSerializer, NotificationtypeSerializer
from push_notifications.models import GCMDevice  
from .models import NotificationReceiver
from django.shortcuts import get_object_or_404
from .models import notifications 
from rest_framework.pagination import LimitOffsetPagination
from rest_framework import viewsets
from .models import Notificationtype
from utils.helper import success_response , failed_response
import logging


logger = logging.getLogger('notifications')


class SendEmailNotificationView(APIView):
    def post(self, request):
        logger.info("Starting email notification process.")
        serializer = EmailNotificationSerializer(data=request.data)
        
        if serializer.is_valid():
            try:
                subject = serializer.validated_data['subject']
                message = serializer.validated_data['message']
                recipient_email = serializer.validated_data['recipient_email']
                
                logger.info(f"Sending email to {recipient_email} with subject '{subject}'.")
                send_mail(
                    subject,
                    message,
                    'your_email@example.com',  
                    [recipient_email],
                    fail_silently=False,
                )
                
                logger.info("Email sent successfully.")
                return success_response(msg="Email sent successfully")
                
            except Exception as e:
                logger.error(f"Failed to send email: {str(e)}", exc_info=True)
                return failed_response({"error": "Failed to send email"}, status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        logger.warning(f"Validation failed: {serializer.errors}")
        return failed_response(serializer.errors, status.HTTP_400_BAD_REQUEST)




class SendAppNotificationView(APIView):
    def post(self, request):
        logger.info("Starting app notification process.")
        serializer = AppNotificationSerializer(data=request.data)
        
        if serializer.is_valid():
            try:
                title = serializer.validated_data['title']
                message = serializer.validated_data['message']
                recipient_id = serializer.validated_data['recipient_id']
                
                logger.info(f"Sending notification to user ID {recipient_id} with title '{title}'.")
                
                devices = GCMDevice.objects.filter(user__id=recipient_id)
                
                if devices.exists():
                    devices.send_message(message, title=title)
                    logger.info(f"Notification sent to user ID {recipient_id}.")
                    return success_response(msg="Notification sent successfully")
                else:
                    logger.warning(f"Recipient with user ID {recipient_id} not found.")
                    return failed_response("Recipient not found", status.HTTP_404_NOT_FOUND)

            except Exception as e:
                logger.error(f"Failed to send app notification: {str(e)}", exc_info=True)
                return failed_response({"error": "Failed to send notification"}, status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        logger.warning(f"Validation failed: {serializer.errors}")
        return failed_response(serializer.errors, status.HTTP_400_BAD_REQUEST)


class NotificationCreateView(APIView):
    def post(self, request):
        serializer = NotificationsSerializer(data=request.data)
        if serializer.is_valid():
            notification = serializer.save()
            return success_response(
                data={"notification_id": notification.id},
                msg="Notification created successfully"
            )
        return failed_response(serializer.errors, status.HTTP_400_BAD_REQUEST)


class NotificationtypeCreateView(APIView):
    def post(self, request):
        serializer = NotificationtypeSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return success_response(
                data=serializer.data,
                msg="Notification type created successfully"
            )
        return failed_response(serializer.errors, status.HTTP_400_BAD_REQUEST)


class NotificationsCreateView(APIView):
    def post(self, request):
        logger.info("Starting the notification creation process.")
        
        serializer = NotificationsSerializer(data=request.data)
        
        if serializer.is_valid():
            try:
                serializer.save()
                logger.info(f"Notification created successfully with data: {serializer.data}")
                
                return success_response(
                    data=serializer.data,
                    msg="Notification created successfully"
                )
            except Exception as e:
                logger.error(f"Failed to create notification: {str(e)}", exc_info=True)
                return failed_response({"error": "Failed to create notification"}, status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        logger.warning(f"Validation failed: {serializer.errors}")
        return failed_response(serializer.errors, status.HTTP_400_BAD_REQUEST)

class NotificationReceiverCreateView(APIView):
    def post(self, request):
        logger.info("Starting the notification receiver creation process.")
        
        serializer = NotificationReceiverSerializer(data=request.data)
        
        if serializer.is_valid():
            try:
                notification_receiver = serializer.save()
                logger.info(f"Notification receiver created successfully with ID: {notification_receiver.id}")
                
                return success_response(
                    data={"notification_receiver_id": notification_receiver.id},
                    msg="Notification receiver created successfully"
                )
            except Exception as e:
                logger.error(f"Failed to create notification receiver: {str(e)}", exc_info=True)
                return failed_response({"error": "Failed to create notification receiver"}, status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        logger.warning(f"Validation failed: {serializer.errors}")
        return failed_response(serializer.errors, status.HTTP_400_BAD_REQUEST)


class ReadNotificationsView(APIView):
    def get(self, request, user_id):
        logger.info(f"Fetching notifications for user_id: {user_id}")

        try:
            receivers = NotificationReceiver.objects.filter(user_id=user_id).select_related('notification')

            if not receivers:
                logger.warning(f"No notifications found for user_id: {user_id}")
                return failed_response("No notifications found for this user.", status.HTTP_404_NOT_FOUND)

            notifications_data = []
            for receiver in receivers:
                notification = receiver.notification
                notification_data = {
                    "notification": {
                        "notification_type": {
                            "type": notification.notification_type.type,
                        },
                        "sender_id": notification.sender_id,
                        "read_at": notification.read_at,
                        "data": notification.data,
                    },
                    "user_id": receiver.user_id
                }
                notifications_data.append(notification_data)

            logger.info(f"Found {len(notifications_data)} notifications for user_id: {user_id}")

            return success_response(data=notifications_data)
        
        except Exception as e:
            logger.error(f"Error while fetching notifications for user_id: {user_id} - {str(e)}", exc_info=True)
            return failed_response("An error occurred while fetching notifications.", status.HTTP_500_INTERNAL_SERVER_ERROR)



class DeleteNotificationView(APIView):
    def delete(self, request, notification_id):
        logger.info(f"Attempting to delete notification with id: {notification_id}")
        
        try:
            notification = get_object_or_404(notifications, id=notification_id)
            notification.delete()

            logger.info(f"Notification with id: {notification_id} deleted successfully.")
            return success_response(msg="Notification deleted successfully")

        except Exception as e:
            logger.error(f"Error occurred while trying to delete notification with id: {notification_id} - {str(e)}", exc_info=True)
            return failed_response("An error occurred while deleting the notification.", status.HTTP_500_INTERNAL_SERVER_ERROR)



class PaginatedNotificationReceiverView(APIView, LimitOffsetPagination):
    def get(self, request, user_id):
        logger.info(f"Received request to fetch notifications for user_id: {user_id}")

        try:
            notification_receivers = NotificationReceiver.objects.filter(user_id=user_id).select_related('notification')

            results = self.paginate_queryset(notification_receivers, request, view=self)

            if not results:
                logger.info(f"No notifications found for user_id: {user_id}")
                return failed_response("No notifications found for this user.", status.HTTP_404_NOT_FOUND)

            serializer = NotificationReceiverSerializer(results, many=True)

            logger.info(f"Successfully fetched notifications for user_id: {user_id}")
            return success_response(data=self.get_paginated_response(serializer.data).data)

        except Exception as e:
            logger.error(f"Error occurred while fetching notifications for user_id: {user_id} - {str(e)}", exc_info=True)
            return failed_response("An error occurred while fetching notifications.", status.HTTP_500_INTERNAL_SERVER_ERROR)


class NotificationtypeAdminViewSet(viewsets.ModelViewSet):
    queryset = Notificationtype.objects.all()
    serializer_class = NotificationtypeSerializer

    def create(self, request, *args, **kwargs):
        logger.info(f"Received request to create a new notification type with data: {request.data}")

        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            try:
                serializer.save()
                logger.info(f"Notification type created successfully with data: {serializer.data}")
                return success_response(
                    data=serializer.data,
                    msg="Notification type created successfully"
                )
            except Exception as e:
                logger.error(f"Error occurred while creating notification type: {str(e)}", exc_info=True)
                return failed_response("An error occurred while creating the notification type.", status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            logger.warning(f"Validation failed for the notification type creation request. Errors: {serializer.errors}")
            return failed_response(serializer.errors, status.HTTP_400_BAD_REQUEST)
