# Path: event_exim/models.py
# class EventDupeGuesses(models.Model):
#     source_event = models.ForeignKey(Event, related_name='dupe_guesses')
#     dupe_event = models.ForeignKey(Event, related_name='dupe_guess_sources')
# 
#     decision = models.IntegerField(choices=((0, 'undecided'),
#                                             (1, 'not a duplicate'),
#                                             (2, 'yes, duplicates')),
#                                    verbose_name='Status',
#                                    null=True,
#                                    blank=True
#                                    )
# 
#     class Meta:
#         unique_together = (('source_event', 'dupe_event'),)
# 
#     @staticmethod
#     def get_potential_dupes(last_update=None):
#         """
#             Things that will muddle screening for duplicates:
#             * Bad data, e.g. zip code typos, errors converting local time to starts_at_utc.
#             * Missing data, e.g. virtual events with no zip code/location data
#             Returns a QuerySet of zip + starts_at_utc pairs which match more than one event.
#         """
#         if last_update is None:
#             return (
#                 Event.objects.values('zip', 'starts_at_utc')
#                 .annotate(count=Count('id'))
#                 .order_by()
#                 .filter(
#                     count__gt=1,
#                     zip__isnull=False,
#                     starts_at_utc__isnull=False,
#                     status='active'
#                 )
#                 .exclude(zip='')
#             )
#         # For ONLY new events, compare to all events to check for duplicates
#         new_events = Event.objects.values('zip', 'starts_at_utc').order_by().filter(
#                 dupe_id__isnull=True,
#                 zip__isnull=False,
#                 starts_at_utc__isnull=False,
#                 updated_at__gt=last_update,
#                 status='active'
#             ).exclude(zip='')
#         dupe_events = Event.objects.values('zip', 'starts_at_utc').annotate(count=Count('id')).none()
#         for new_event in new_events:
#             dupes = Event.objects.values('zip', 'starts_at_utc').annotate(count=Count('id')).filter(
#                 zip=new_event['zip'], starts_at_utc=new_event['starts_at_utc'],
#                 count__gt=1,
#                 dupe_id__isnull=True,
#                 status='active'
#             )
#             dupe_events = dupe_events.union(dupes)
#         return dupes
# 
#     @ staticmethod
#     def record_potential_dupes(potential_dupes):
#         message = 'Recording new potential duplicate events: \n'
#         for dupe in potential_dupes:
#             events = (
#                 Event.objects
#                 .filter(zip=dupe['zip'], starts_at_utc=dupe['starts_at_utc'])
#                 .order_by('id')
#             )
#             for x in range(dupe['count']):
#                 for y in range(x+1, dupe['count']):
#                     source_event = events[x]
#                     dupe_event = events[y]
#                     answer = EventDupeGuesses.objects.get_or_create(
#                         source_event=source_event,
#                         dupe_event=dupe_event,
#                         decision=0
#                     )
#                     if not answer[1]:
#                         message += (
#                             "Duplicate event guess for {} and {} already recorded \n"
#                             .format(source_event.id, dupe_event.id)
#                         )
#                     else:
#                         message += (
#                             "Recorded duplicate guess: Events {} and {} \n"
#                             .format(source_event.id, dupe_event.id)
#                         )
#         return message
# 
#     # Currently doesn't handle the case where an event has more than one duplicate.
#     # Implementing this should wait until we have a clear use case for dupe_id on events
#     # @receiver(post_save, sender = EventDupeGuesses, dispatch_uid = 'update_event_dupe')
#     # def update_event_dupe_id(sender, instance, **kwargs):
#     #     print("now in post save!")
#     #     # yes, a duplicate
#     #     if instance.decision == 2:
#     #         instance.dupe_event.dupe_id = instance.source_event_id
#     #         instance.dupe_event.save()
#     #         print("recording dupe id %s on event %s" %(instance.source_event_id, instance.dupe_event.id))
#     #     # undecided or not a duplicate
#     #     elif instance.decision == 1 or instance.decision == 0 or instance.decision == None:
#     #         instance.dupe_event.dupe_id = None
#     #         instance.dupe_event.save()
#     #         print("event %s dupe_id set to None" % instance.dupe_event.id)


from datetime import datetime, timedelta
from django.conf import settings
from django.core.management.base import BaseCommand
from event_exim.models import EventDupeGuesses


class Command(BaseCommand):

    help = ('Checks events across all sources for events in the same zip code '
            'at the same UTC start time and marks them as potential dupes for review.')

    def handle(self, *args, **options):
        dupes = EventDupeGuesses.get_potential_dupes()
        if dupes:

# Path: event_exim/models.py
# class EventDupeGuesses(models.Model):
#     source_event = models.ForeignKey(Event, related_name='dupe_guesses')
#     dupe_event = models.ForeignKey(Event, related_name='dupe_guess_sources')
# 
#     decision = models.IntegerField(choices=((0, 'undecided'),
#                                             (1, 'not a duplicate'),
#                                             (2, 'yes, duplicates')),
#                                    verbose_name='Status',
#                                    null=True,
#                                    blank=True
#                                    )
# 
#     class Meta:
#         unique_together = (('source_event', 'dupe_event'),)
# 
#     @staticmethod
#     def get_potential_dupes(last_update=None):
#         """
#             Things that will muddle screening for duplicates:
#             * Bad data, e.g. zip code typos, errors converting local time to starts_at_utc.
#             * Missing data, e.g. virtual events with no zip code/location data
#             Returns a QuerySet of zip + starts_at_utc pairs which match more than one event.
#         """
#         if last_update is None:
#             return (
#                 Event.objects.values('zip', 'starts_at_utc')
#                 .annotate(count=Count('id'))
#                 .order_by()
#                 .filter(
#                     count__gt=1,
#                     zip__isnull=False,
#                     starts_at_utc__isnull=False,
#                     status='active'
#                 )
#                 .exclude(zip='')
#             )
#         # For ONLY new events, compare to all events to check for duplicates
#         new_events = Event.objects.values('zip', 'starts_at_utc').order_by().filter(
#                 dupe_id__isnull=True,
#                 zip__isnull=False,
#                 starts_at_utc__isnull=False,
#                 updated_at__gt=last_update,
#                 status='active'
#             ).exclude(zip='')
#         dupe_events = Event.objects.values('zip', 'starts_at_utc').annotate(count=Count('id')).none()
#         for new_event in new_events:
#             dupes = Event.objects.values('zip', 'starts_at_utc').annotate(count=Count('id')).filter(
#                 zip=new_event['zip'], starts_at_utc=new_event['starts_at_utc'],
#                 count__gt=1,
#                 dupe_id__isnull=True,
#                 status='active'
#             )
#             dupe_events = dupe_events.union(dupes)
#         return dupes
# 
#     @ staticmethod
#     def record_potential_dupes(potential_dupes):
#         message = 'Recording new potential duplicate events: \n'
#         for dupe in potential_dupes:
#             events = (
#                 Event.objects
#                 .filter(zip=dupe['zip'], starts_at_utc=dupe['starts_at_utc'])
#                 .order_by('id')
#             )
#             for x in range(dupe['count']):
#                 for y in range(x+1, dupe['count']):
#                     source_event = events[x]
#                     dupe_event = events[y]
#                     answer = EventDupeGuesses.objects.get_or_create(
#                         source_event=source_event,
#                         dupe_event=dupe_event,
#                         decision=0
#                     )
#                     if not answer[1]:
#                         message += (
#                             "Duplicate event guess for {} and {} already recorded \n"
#                             .format(source_event.id, dupe_event.id)
#                         )
#                     else:
#                         message += (
#                             "Recorded duplicate guess: Events {} and {} \n"
#                             .format(source_event.id, dupe_event.id)
#                         )
#         return message
# 
#     # Currently doesn't handle the case where an event has more than one duplicate.
#     # Implementing this should wait until we have a clear use case for dupe_id on events
#     # @receiver(post_save, sender = EventDupeGuesses, dispatch_uid = 'update_event_dupe')
#     # def update_event_dupe_id(sender, instance, **kwargs):
#     #     print("now in post save!")
#     #     # yes, a duplicate
#     #     if instance.decision == 2:
#     #         instance.dupe_event.dupe_id = instance.source_event_id
#     #         instance.dupe_event.save()
#     #         print("recording dupe id %s on event %s" %(instance.source_event_id, instance.dupe_event.id))
#     #     # undecided or not a duplicate
#     #     elif instance.decision == 1 or instance.decision == 0 or instance.decision == None:
#     #         instance.dupe_event.dupe_id = None
#     #         instance.dupe_event.save()
#     #         print("event %s dupe_id set to None" % instance.dupe_event.id)


# Path: event_exim/management/commands/event_dupe_finder.py
from datetime import datetime, timedelta
from django.conf import settings
from django.core.management.base import BaseCommand
from event_exim.models import EventDupeGuesses



class Command(BaseCommand):

    help = ('Checks events across all sources for events in the same zip code '
            'at the same UTC start time and marks them as potential dupes for review.')

    def handle(self, *args, **options):
        dupes = EventDupeGuesses.get_potential_dupes()
        if dupes:

            log = EventDupeGuesses.record_potential_dupes(dupes)