import logging
from collections import Counter
from django.core.management.base import BaseCommand
from django.db.models import Q

from TWLight.applications.models import Application
from TWLight.resources.models import Partner
from TWLight.applications.signals import Reminder
from TWLight.users.models import Editor

logger = logging.getLogger(__name__)


class Command(BaseCommand):
    def handle(self, *args, **options):
        # This is not DRY. Originally, this pulled the queryset from
        # TWLight.applications.views.ListApplicationsView.get_queryset().
        # But that now expects a request object. So, we did a copy/paste.
        # We're actually getting apps with a status of PENDING or QUESTION
        # or APPROVED, and their corresponding user preferences being True
        # for partners with a status of AVAILABLE.
        all_apps = (
            Application.objects.filter(
                Q(
                    partner__coordinator__editor__user__userprofile__pending_app_reminders=True
                )
                & Q(status=Application.PENDING)
                | Q(
                    partner__coordinator__editor__user__userprofile__discussion_app_reminders=True
                )
                & Q(status=Application.QUESTION)
                | Q(
                    partner__coordinator__editor__user__userprofile__approved_app_reminders=True
                )
                & Q(status=Application.APPROVED),
                partner__status__in=[Partner.AVAILABLE],
                editor__isnull=False,
            )
            .exclude(editor__user__groups__name="restricted")
            .order_by("status", "partner", "date_created")
        )
        # A deduplicated dict of coordinators from the pending app queryset, along
        # with a count of how many total pending apps they have
        coordinators = Counter(
            all_apps.values_list(
                "partner__coordinator__editor",
                "partner__coordinator__email",
                "partner__coordinator__editor__user__userprofile__lang",
            )
        )

        for coordinator, count in list(coordinators.items()):
            try:
                # We create a dictionary with the three status codes
                # we'd want to send emails for, and their corresponding
                # counts.
                app_status_and_count = {
                    Application.PENDING: all_apps.filter(
                        status=Application.PENDING,
                        partner__coordinator__editor=coordinator[0],
                    ).count(),
                    Application.QUESTION: all_apps.filter(
                        status=Application.QUESTION,
                        partner__coordinator__editor=coordinator[0],
                    ).count(),
                    Application.APPROVED: all_apps.filter(
                        status=Application.APPROVED,
                        partner__coordinator__editor=coordinator[0],
                    ).count(),
                }
                editor = Editor.objects.get(id=coordinator[0])
            except Editor.DoesNotExist:
                logger.info(
                    "Editor {} does not exist; skipping.".format(coordinator[0])
                )
                break
            # Only bother with the signal if we have a coordinator email.
            if coordinator[1]:
                Reminder.coordinator_reminder.send(
                    sender=self.__class__,
                    app_status_and_count=app_status_and_count,
                    coordinator_wp_username=editor.wp_username,
                    coordinator_email=coordinator[1],
                    coordinator_lang=coordinator[2],
                )

[(11, 'logging.getLogger', 'logging.getLogger', False, 'import logging\n'), (71, 'TWLight.users.models.Editor.objects.get', 'Editor.objects.get', False, 'from TWLight.users.models import Editor\n'), (79, 'TWLight.applications.signals.Reminder.coordinator_reminder.send', 'Reminder.coordinator_reminder.send', False, 'from TWLight.applications.signals import Reminder\n'), (32, 'django.db.models.Q', 'Q', False, 'from django.db.models import Q\n'), (35, 'django.db.models.Q', 'Q', False, 'from django.db.models import Q\n'), (24, 'django.db.models.Q', 'Q', False, 'from django.db.models import Q\n'), (27, 'django.db.models.Q', 'Q', False, 'from django.db.models import Q\n'), (28, 'django.db.models.Q', 'Q', False, 'from django.db.models import Q\n'), (31, 'django.db.models.Q', 'Q', False, 'from django.db.models import Q\n')]