from django.http import JsonResponse, HttpResponseNotFound
from django.views.decorators.csrf import csrf_exempt
from tastypie.exceptions import BadRequest

from corehq import privileges
from corehq.apps.accounting.decorators import requires_privilege_with_fallback
from corehq.apps.api.decorators import allow_cors
from corehq.apps.api.resources.messaging_event.filters import filter_query
from corehq.apps.api.resources.messaging_event.pagination import get_paged_data
from corehq.apps.api.resources.messaging_event.serializers import serialize_event
from corehq.apps.api.resources.messaging_event.utils import sort_query, get_request_params
from corehq.apps.case_importer.views import require_can_edit_data
from corehq.apps.domain.decorators import api_auth
from corehq.apps.sms.models import MessagingSubEvent


@csrf_exempt
@allow_cors(['OPTIONS', 'GET'])
@api_auth
@require_can_edit_data
@requires_privilege_with_fallback(privileges.API_ACCESS)
def messaging_events(request, domain, event_id=None):
    """Despite it's name this API is backed by the MessagingSubEvent model
    which has a more direct relationship with who the messages are being sent to.
    Each event may have more than one actual message associated with it.
    """
    try:
        if request.method == 'GET' and event_id:
            return _get_individual(request, event_id)
        if request.method == 'GET' and not event_id:
            return _get_list(request)
        return JsonResponse({'error': "Request method not allowed"}, status=405)
    except BadRequest as e:
        return JsonResponse({'error': str(e)}, status=400)


def _get_individual(request, event_id):
    try:
        event = MessagingSubEvent.objects.select_related("parent").get(
            parent__domain=request.domain, id=event_id
        )
    except MessagingSubEvent.DoesNotExist:
        return HttpResponseNotFound()

    return JsonResponse(serialize_event(event))


def _get_list(request):
    request_params = get_request_params(request)
    query = MessagingSubEvent.objects.select_related("parent").filter(parent__domain=request.domain)
    filtered_query = filter_query(query, request_params)
    sorted_query = sort_query(filtered_query, request_params)
    data = get_paged_data(sorted_query, request_params)
    return JsonResponse(data)

@@ -1,20 +1,116 @@
+from django.db.models import OuterRef, Subquery%0Afrom django.db.models.functions import Greatest%0A
 from django.http imp
@@ -148,16 +148,16 @@
 otFound%0A
-
 from dja
@@ -901,16 +901,28 @@
 SubEvent
+, SMS, Email
 %0A%0A%0A@csrf
@@ -2123,81 +2123,24 @@
 y = 
-MessagingSubEvent.objects.select_related(%22parent%22).filter(parent__domain=
+_get_base_query(
 requ
@@ -2322,24 +2322,24 @@
 est_params)%0A
-
     return J
@@ -2356,8 +2356,627 @@
 e(data)%0A
+%0A%0Adef _get_base_query(domain):%0A    query = MessagingSubEvent.objects.select_related(%22parent%22).filter(parent__domain=domain)%0A    newest_sms = (%0A        SMS.objects.filter(messaging_subevent=OuterRef('pk'))%0A        .order_by('-date_modified')%0A        .values('date_modified')%5B:1%5D%0A    )%0A    newest_email = (%0A       Email.objects.filter(messaging_subevent=OuterRef('pk'))%0A       .order_by('-date_modified')%0A       .values('date_modified')%5B:1%5D%0A    )%0A    query = query.annotate(date_last_activity=Greatest(%0A        'date', 'xforms_session__modified_time', Subquery(newest_sms), Subquery(newest_email)%0A    ))%0A    return query%0A

update base query to get date_last_activity