# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.conf import settings
from django.db import transaction
from django.db.models import aggregates

from core import exceptions
from core.utils import dates


REGISTERED_TRIGGERS = [
    (0, 'None'),
    (1, 'None'),
    (2, 'None'),
    (3, 'None'),
    (4, 'None'),
    (5, 'best_verified_bug'),
    (6, 'yandex_sponsored'),
]


class TriggerNotFound(exceptions.CoreException):
    pass


class Registry(object):

    def __init__(self):
        self._registry = dict(REGISTERED_TRIGGERS)
        self._trigger_names = dict(zip(self._registry.values(),
                                       self._registry.keys()))

    def get_trigger(self, trigger_id):
        trigger_name = self._registry.get(trigger_id)
        return self.get_trigger_by_name(trigger_name)

    def get_trigger_by_name(self, trigger_name):
        try:
            trigger = globals()[trigger_name]
        except KeyError:
            raise TriggerNotFound(trigger_name)
        else:
            return trigger

    def get_trigger_id_by_name(self, trigger_name):
        return self._trigger_names.get(trigger_name)

    def registered(self):
        return self._registry.items()


def best_verified_bug(badge_id):
    from core import models
    max_points = models.Reward.effective.aggregate(
        points=aggregates.Max('points'))
    rewards = models.Reward.effective.filter(**max_points)
    last_best_reporter = rewards.latest('payment_created').reporter
    badge = models.Badge.objects.get(pk=badge_id)
    with transaction.atomic():
        if badge.exclusive_holder_changes(last_best_reporter):
            badge.deprive_exclusive_holder()
        badge.award(last_best_reporter)


def yandex_sponsored(badge_id):
    from core import models
    badge = models.Badge.objects.get(pk=badge_id)
    rewards = models.Reward.effective.filter(
        payment_created__range=dates.get_range_for_last(days=30))
    active_reporters_ids = (
        rewards
        .order_by('reporter')
        .values('reporter')
        .annotate(rewards_per_reporter=aggregates.Count('reporter'))
        .filter(rewards_per_reporter__gte=settings.YANDEX_SPONSORED_THRESHOLD)
        .values_list('reporter', flat=True)
    )
    for reporter_id in active_reporters_ids:
        reporter = models.Reporter.objects.get(pk=reporter_id)
        if badge.is_not_assigned(reporter):
            badge.award(reporter)
