from itertools import groupby

from django.db import models
from django_softdelete.models import SoftDeleteModel, SoftDeleteManager


class ItemManager(SoftDeleteManager):

    def create(self, **kwargs):
        container = kwargs.pop('container')
        if 'uid_deprecated' in kwargs:
            raise ValueError('uid_deprecated must not be set manually')
        uid_deprecated = Item.all_objects.filter(event=kwargs['event']).count() + 1
        kwargs['uid_deprecated'] = uid_deprecated
        item = super().create(**kwargs)
        item.container = container
        return item

    def get_queryset(self):
        return super().get_queryset().filter(returned_at__isnull=True)


class Item(SoftDeleteModel):
    id = models.AutoField(primary_key=True)
    uid_deprecated = models.IntegerField()
    description = models.TextField()
    event = models.ForeignKey('Event', models.CASCADE)
    returned_at = models.DateTimeField(blank=True, null=True)
    created_at = models.DateTimeField(null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True)

    @property
    def container(self):
        try:
            return self.container_history.order_by('-timestamp').first().container
        except AttributeError:
            return None

    @container.setter
    def container(self, value):
        if self.container == value:
            return
        self.container_history.create(container=value)

    @property
    def related_issues(self):
        groups = groupby(self.issue_relation_changes.all(), lambda rel: rel.issue_thread.id)
        return [sorted(v, key=lambda r: r.timestamp)[0].issue_thread for k, v in groups]

    objects = ItemManager()
    all_objects = models.Manager()

    class Meta:
        unique_together = (('uid_deprecated', 'event'),)
        permissions = [
            ('match_item', 'Can match item')
        ]

    def __str__(self):
        return '[' + str(self.id) + ']' + self.description


class Container(SoftDeleteModel):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    created_at = models.DateTimeField(blank=True, null=True)
    updated_at = models.DateTimeField(blank=True, null=True)

    @property
    def items(self):
        try:
            history = self.item_history.order_by('-timestamp').all()
            return [v for k, v in groupby(history, key=lambda item: item.item.id)]
        except AttributeError:
            return []

    def __str__(self):
        return '[' + str(self.id) + ']' + self.name


class ItemPlacement(models.Model):
    id = models.AutoField(primary_key=True)
    item = models.ForeignKey('Item', models.CASCADE, related_name='container_history')
    container = models.ForeignKey('Container', models.CASCADE, related_name='item_history')
    timestamp = models.DateTimeField(auto_now_add=True)


class Comment(models.Model):
    id = models.AutoField(primary_key=True)
    item = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='comments')
    comment = models.TextField()
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return str(self.item) + ' comment #' + str(self.id)


class Event(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    slug = models.CharField(max_length=255, unique=True)
    start = models.DateTimeField(blank=True, null=True)
    end = models.DateTimeField(blank=True, null=True)
    pre_start = models.DateTimeField(blank=True, null=True)
    post_end = models.DateTimeField(blank=True, null=True)
    created_at = models.DateTimeField(null=True, auto_now_add=True)
    updated_at = models.DateTimeField(blank=True, null=True)

    def __str__(self):
        return '[' + str(self.slug) + ']' + self.name

    class Meta:
        db_table = 'common_event'