from django.db import models
from django.forms import ModelForm
from django.contrib.auth.models import User

class Queue(models.Model):
    name = models.CharField('name', max_length=10)

    def __unicode__(self):
        return self.name

class Comment(models.Model):
    owner  = models.ForeignKey(User)
    text   = models.TextField('comment text', max_length=1000, blank=True, null=True)
    repto  = models.ForeignKey('self', null=True)
    ticket = models.ForeignKey('Ticket', null=True)
    date   = models.DateTimeField('date', null=True, auto_now_add=True)

    def __unicode__(self):
        return self.text

    @staticmethod
    def __get_comments_tree( root ):
        comments = []
        for comment in root:
            comments.append( comment )
            if len( comment.comment_set.all() ) > 0:
                comments.append( '>>>' )
                comments.extend( Comment.__get_comments_tree( comment.comment_set.all() ) )
                comments.append( '<<<' )
        return comments

    @staticmethod
    def get_related_comments( id ):
        from django.db.models import Q
        comments_root = Comment.objects.filter(Q(ticket=id) & Q(repto__isnull=True))
        return Comment.__get_comments_tree( comments_root )

class TicketManager(models.Manager):
    def search(self, search_terms):
        import operator
        from django.db.models import Q
        terms = [term.strip() for term in search_terms.split()]
        q_objects = []

        for term in terms:
            q_objects.append(Q(s_desc__icontains=term))
            q_objects.append(Q(l_desc__icontains=term))

        qs = self.get_query_set()

        return qs.filter(reduce(operator.or_, q_objects))

class Ticket(models.Model):
    URG_CH = (
        (5, 'emergency'),
        (4, 'high'),
        (3, 'important'),
        (2, 'normal'),
        (1, 'low')
    )

    STAT_CH = (
        (0, 'new'),
        (1, 'open'),
        (2, 'stalled'),
        (3, 'rejected'),
        (4, 'deleted'),
        (5, 'resolved')
    )

    s_desc = models.CharField('short description', max_length=100)
    l_desc = models.TextField('description', max_length=1000, blank=True, null=True)
    creator= models.ForeignKey(User, related_name='creator')
    resp   = models.ForeignKey(User, related_name='responsible', blank=True, null=True)
    urg    = models.PositiveIntegerField('urgency', choices=URG_CH, default='3')
    s_date = models.DateTimeField('created', null=True, auto_now_add=True)
    e_date = models.DateField('deadline', blank=True, null=True)
    d_date = models.DateTimeField('done_date', null=True, blank=True)
    status = models.PositiveIntegerField('status', choices=STAT_CH, default='0')
    queue  = models.ForeignKey(Queue)
    done   = models.BooleanField(default=False)
    subscr = models.ManyToManyField(User)
    objects = TicketManager()

    def __unicode__(self):
        return self.s_desc

    def get_urgency(self):
        return filter(lambda x: x[0] == self.urg, self.URG_CH)[0][1]

    def get_status(self):
        return filter(lambda x: x[0] == self.status, self.STAT_CH)[0][1]

    @staticmethod
    def get_foo_byname(type, name):
        bar = {
            'status' : lambda y: filter(lambda x: x[1] == str(y), Ticket.STAT_CH)[0][0],
            'urg'    : lambda y: filter(lambda x: x[1] == str(y), Ticket.URG_CH)[0][0],
            'resp'   : lambda x: User.objects.get(username=x),
            'creator': lambda x: User.objects.get(username=x),
            'queue'  : lambda x: Queue.objects.get(name=x),
        }

        try:
            return bar[type](name)
        except:
            if type == 'status' or type == 'urg':
                return None
            return name

class TicketForm(ModelForm):
    class Meta:
        exclude = ('creator', 'done', 'subscr', 'd_date')
        model = Ticket

