# -'- Encoding: utf-8 -*-

from django.core.urlresolvers import reverse
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.timezone import now
from django.utils.translation import ugettext as _

from utils import COUNTRIES, OverwriteStorage
from gallery.models import Photo
from kasu import image_models


def get_upload_path(instance, filename):
    """
    Generates the desired file path and filename for an uploaded Image.
    With this function Django can save the uploaded images to subfolders that
    also have a meaning for humans.

    @param instance: an Django Object for which the Image has been uploaded.
    @type instance: a instace of an models.Model sub-class.
    @param filename: The filename of the uploaded image.
    @type filename: String
    """
    extension = filename[filename.rfind('.') + 1:]
    if isinstance(instance, Event):
        if instance.id:
            return "events/%s.%s" % (instance.id, extension)
        else:
            return "events/%s.%s" % (slugify(instance.name), extension)
    elif isinstance(instance, Location):
        if instance.id:
            return "events/location/%s.%s" % (instance.id, extension)
        else:
            return "events/location/%s.%s" % (instance.id, extension)
    elif isinstance(instance, Photo):
        return "events/%s/%s" % (instance.event.id, filename)


class EventManager(models.Manager):
    def current_event(self):
        try:
            current = self.filter(start__lte=now())
            current = current.filter(end__gte=now())
            return current.order_by('start', 'end')[0]
        except:
            return None

    def next_event(self):
        try:
            return self.filter(start__gt=now()).order_by('start', 'end')[0]
        except:
            return None

    def archive(self):
        return self.filter(start__lt=now())

    def upcoming(self, limit=3):
        result = self.filter(start__gt=now()).order_by('start', 'end')
        if limit:
            return result[1:(limit + 1)]
        else:
            return result


class Event(image_models.ImageModel):
    name = models.CharField(_('Name'), max_length=255)
    description = models.TextField(_("Description"), blank=True)
    location = models.ForeignKey('Location')
    start = models.DateTimeField(_('Start'))
    end = models.DateTimeField(_('End'), blank=True, null=True)
    url = models.URLField(_('Homepage'), blank=True)
    image = models.ImageField(_("Image"), upload_to=get_upload_path,
                              storage=OverwriteStorage(), blank=True, null=True)
    mahjong_tournament = models.BooleanField(_('Mahjong Tournament'), default=False,
        help_text=_(u'This event is a tournament, different rules apply for \
        the kyu ranking.'))
    mahjong_season = models.PositiveSmallIntegerField(_('Mahjong Season'), blank=True, null=True)
    photo_count = models.PositiveIntegerField(default=0, editable=False)
    event_series = models.ForeignKey('Event', blank=True, null=True,
        on_delete=models.SET_NULL, editable=False,
        verbose_name=_('Event Series'),
        help_text=_(u'Wenn dieser Event zu einer Veranstaltungsreihe gehört \
        werden Ort, Beschreibung, Bild und Homepage von dem hier angegebenen \
        Event übernommen.')
    )
    objects = EventManager()

    class Meta(object):
        verbose_name = _('Event')
        verbose_name_plural = _('Events')
        ordering = ('-start', '-end',)

    def __unicode__(self):
        try:
            return "%(name)s (%(date)s)" % {'name': self.name,
                                            'date': self.start.date()}
        except:
            return "New Event Model"

    def get_absolute_url(self):
        kwargs = {
            'pk': self.id,
            'year': self.start.strftime('%Y'),
            'month': self.start.strftime('%m')
        }
        return reverse('event-detail', kwargs=kwargs)

    def get_eventseries_form_url(self):
        kwargs = {
            'pk': self.id,
            'year': self.start.strftime('%Y'),
            'month': self.start.strftime('%m')
        }
        return reverse('eventseries-form', kwargs=kwargs)

    def get_edit_url(self):
        kwargs = {
            'pk': self.id,
            'year': self.start.strftime('%Y'),
            'month': self.start.strftime('%m')
        }
        return reverse('event-form', kwargs=kwargs)

    def get_callout(self):
        if self.image:
            return self.callout
        elif self.photo_set.count():
            return self.photo_set.all().order_by('?')[0].callout
        elif self.location.image:
            return self.location.callout
        else:
            return None

    def get_thumbnail(self):
        if self.image:
            return self.thumbnail
        elif self.photo_set.count():
            return self.photo_set.all().order_by('?')[0].thumbnail
        elif self.location.image:
            return self.location.thumbnail
        else:
            return None

    def save(self, **kwargs):
        # Fülle fehlende Felder mit den Angaben der Hauptveranstaltung aus.
        if self.event_series:
            master_event = self.event_series
            self.name = self.name or master_event.name
            self.description = self.description or master_event.description
            self.location = master_event.location
            self.url = master_event.url
            self.image = self.image or master_event.image
        self.photo_count = self.photo_set.count()
        super(Event, self).save(**kwargs)

        # Update the Hanchans if necesery:
        for hanchan in self.hanchan_set.all():
            hanchan.save()


class Location(image_models.ImageModel):
    name = models.CharField(_("Name"), max_length=200)
    description = models.TextField(_("Description"), blank=True)
    image = models.ImageField(_("Image"), upload_to=get_upload_path,
                              storage=OverwriteStorage(), blank=True, null=True)
    url = models.URLField(_('Homepage'), blank=True)
    postal_code = models.CharField(_('Postal Code'), max_length=6)
    street_address = models.CharField(_('Street Address'), max_length=127)
    locality = models.CharField(_('Locality'), max_length=127)
    country = models.CharField(_('Country'), max_length=2, choices=COUNTRIES)

    class Meta(object):
        verbose_name = _('Venue')
        verbose_name_plural = _('Venues')

    def __unicode__(self):
        return self.name

    @property
    def address(self):
        address = (self.street_address, self.locality, self.country,)
        return ','.join(address)


models.signals.post_save.connect(image_models.regenerate_image_cache,
                                 sender=Event)
models.signals.post_save.connect(image_models.regenerate_image_cache,
                                 sender=Location)