from django.utils import timezone
from rest_framework import permissions, status
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.notifications.models import Notification, UserDeviceToken
from apps.notifications.serializers import NotificationSerializer, UserDeviceTokenSerializer


class UserNotificationsView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        page_size_raw = request.query_params.get('page_size', '20')
        page_raw = request.query_params.get('page', '1')
        try:
            page_size = max(1, min(100, int(page_size_raw)))
        except Exception:
            page_size = 20
        try:
            page = max(1, int(page_raw))
        except Exception:
            page = 1

        qs = Notification.objects.filter(user=request.user, channel='in_app').order_by('-created_at')
        unread_count = qs.filter(is_read=False).count()

        start = (page - 1) * page_size
        end = start + page_size
        page_qs = qs[start:end]

        serializer = NotificationSerializer(page_qs, many=True)
        results = serializer.data

        for item in results:
            payload = item.get('payload') or {}
            banner_url = payload.get('banner_image_url')
            if banner_url and isinstance(banner_url, str) and banner_url.startswith('/'):
                payload['banner_image_url'] = request.build_absolute_uri(banner_url)
                item['payload'] = payload

        return Response(
            {
                'results': results,
                'count': qs.count(),
                'unread_count': unread_count,
                'page': page,
                'page_size': page_size,
            },
            status=status.HTTP_200_OK,
        )


class MarkNotificationReadView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request, notification_id):
        notif = Notification.objects.filter(id=notification_id, user=request.user, channel='in_app').first()
        if not notif:
            return Response({'detail': 'Not found'}, status=status.HTTP_404_NOT_FOUND)

        if not notif.is_read:
            notif.is_read = True
            notif.read_at = timezone.now()
            notif.save(update_fields=['is_read', 'read_at', 'updated_at'])

        return Response({'success': True}, status=status.HTTP_200_OK)


class MarkAllNotificationsReadView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def post(self, request):
        updated = Notification.objects.filter(user=request.user, channel='in_app', is_read=False).update(is_read=True, read_at=timezone.now())
        return Response({'success': True, 'updated': updated}, status=status.HTTP_200_OK)


class UserDeviceTokenView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):
        qs = UserDeviceToken.objects.filter(user=request.user, is_active=True).order_by('-updated_at')
        return Response(UserDeviceTokenSerializer(qs, many=True).data, status=status.HTTP_200_OK)

    def post(self, request):
        serializer = UserDeviceTokenSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        token = serializer.validated_data['device_token']
        platform = serializer.validated_data.get('platform', 'android')

        obj, _ = UserDeviceToken.objects.update_or_create(
            device_token=token,
            defaults={
                'user': request.user,
                'platform': platform,
                'is_active': serializer.validated_data.get('is_active', True),
            },
        )

        return Response(UserDeviceTokenSerializer(obj).data, status=status.HTTP_200_OK)
