from datetime import datetime

from django.db import models
from django.utils.translation import ugettext as _


class Collection(models.Model):
    name = models.CharField(
        max_length=255, verbose_name=_('name'), unique=True)
    shortname = models.CharField(max_length=30, verbose_name=_('shortname'))

    def __str__(self):
        return '%s' % self.name

    class Meta:
        abstract = True
        ordering = ['name']


class Item(models.Model):
    TARGET_MODEL = None
    TARGET_VERBOSE_NAME = None

    # status choices
    CREATED = 'created'
    STATUS_CHOICES = ((CREATED, _('New')), )
    DEFAULT_CHOICE = CREATED

    name = models.CharField(max_length=255, verbose_name=_('name'))
    achievement = models.PositiveIntegerField(blank=True, null=True, verbose_name=_('achievement'))
    achievement_max = models.PositiveIntegerField(blank=True, null=True, verbose_name=_('out of'))

    def __str__(self):
        return '%s' % self.name

    @classmethod
    def on_class_prepared(cls):
        """
        Add new field 'collection' which is a link to TARGET_MODEL.
        Add new field 'status' which is a list of choices. With CREATED.
        """
        target_field = models.ForeignKey(
            cls.TARGET_MODEL,
            related_name=cls.RELATED_TARGET_NAME,
            verbose_name=_(cls.TARGET_VERBOSE_NAME))
        target_field.contribute_to_class(cls, 'collection')
        status_field = models.CharField(
            max_length=30,
            choices=Item.STATUS_CHOICES + cls.STATUS_CHOICES,
            default=cls.DEFAULT_CHOICE,
            verbose_name=_('status'))
        status_field.contribute_to_class(cls, 'status')
        # check that no other same item name on same collection exists
        cls._meta.unique_together = (('collection', 'name'), )

    class Meta:
        abstract = True
        ordering = ['name']


class Timeline(models.Model):
    """
    Keep changes on collection.
    For an example, a game cretion date. Or when you completed a game.
    """
    TARGET_MODEL = None
    TARGET_VERBOSE_NAME = None
    STATUS_CHOICES = Item.STATUS_CHOICES
    DEFAULT_CHOICE = Item.CREATED
    date = models.DateField(default=datetime.now, verbose_name=_('date'))

    @classmethod
    def on_class_prepared(cls):
        """
        Add new field 'item' which is a link to TARGET_MODEL
        """
        target_field = models.ForeignKey(
            cls.TARGET_MODEL, verbose_name=_(cls.TARGET_VERBOSE_NAME))
        target_field.contribute_to_class(cls, 'item')
        status_field = models.CharField(
            max_length=30,
            choices=Item.STATUS_CHOICES + cls.STATUS_CHOICES,
            default=cls.DEFAULT_CHOICE,
            verbose_name=_('status'))
        status_field.contribute_to_class(cls, 'status')

    def __str__(self):
        return '%s: %s - %s' % (self.date.strftime('%Y-%m-%d'), self.status,
                                self.item)

    class Meta:
        abstract = True
        ordering = ('-date', )
