from __future__ import unicode_literals

from django.contrib.auth import models as admin_models
from django.core.exceptions import ValidationError
from django.db import models
from register.emails import sendgrid_send
from register.utils import reverse

status = [
    ('A', 'Accepted'),
    ('P', 'Pending'),
    ('R', 'Rejected'),
    ('I', 'Invited'),
    ('C', 'Confirmed'),
    ('X', 'Cancelled'),
    ('T', 'Attended'),
]


# Create your models here.

class Application(models.Model):
    id = models.TextField(primary_key=True)
    submission_date = models.DateTimeField()

    # Personal data
    name = models.TextField()
    lastname = models.TextField()
    email = models.EmailField()
    graduation = models.DateField()
    university = models.TextField()
    degree = models.TextField(default='Computer Science')
    under_age = models.NullBooleanField()

    # URLs
    github = models.URLField()
    devpost = models.URLField()
    linkedin = models.URLField()
    site = models.URLField()

    # Self improvement
    first_timer = models.NullBooleanField()
    description = models.TextField()
    projects = models.TextField()
    diet = models.TextField()
    tshirt_size = models.CharField(max_length=3, default='M')
    country = models.TextField()
    scholarship = models.NullBooleanField()
    lennyface = models.TextField(default='-.-')

    # Team
    team = models.NullBooleanField()
    teammates = models.TextField(default='None')

    # Needs to be set to true -> else rejected
    authorized_mlh = models.NullBooleanField()
    status = models.CharField(choices=status, default='P', max_length=2)

    @property
    def positive_votes(self):
        return self.vote_set.filter(vote=1).count()

    @property
    def negative_votes(self):
        return self.vote_set.filter(vote=-1).count()

    @property
    def votes(self):
        total = self.vote_set.count()
        if not total:
            return total
        return self.positive_votes - (self.negative_votes * 3) / total

    # TODO: TEAM EXTERNAL

    def invite(self, request):
        if not request.user.has_perm('register.invite_application'):
            raise ValidationError('User doesn\'t have permission to invite user')
        if self.status != 'A':
            raise ValidationError('Application needs to be accepted to send. Current status: %s' % self.status)
        self._send_invite(request)
        self.status = 'I'
        self.save()

    def confirm(self):
        if self.status != 'I':
            raise ValidationError('Application hasn\'t been invited yet')
        self.status = 'C'
        self.save()

    def cancel(self):
        if self.status != 'C' and self.status != 'I':
            raise ValidationError('Application can\'t be cancelled. Current status: %s' % self.status)
        self.status = 'X'
        self.save()

    def confirmation_url(self, request=None):
        return reverse('confirm_app', kwargs={'token': self.id}, request=request)

    def cancelation_url(self, request=None):
        return reverse('cancel_app', kwargs={'token': self.id}, request=request)

    def _send_invite(self, request):
        sendgrid_send(
            [self.email],
            "[HackUPC] You are invited!",
            {'%name%': self.name,
             '%confirmation_url%': self.confirmation_url(request),
             '%cancellation_url%': self.cancelation_url(request)},
            '513b4761-9c40-4f54-9e76-225c2835b529'
        )

    class Meta:
        permissions = (
            ("accept_application", "Can accept applications"),
            ("invite_application", "Can invite applications"),
            ("attended_application", "Can mark as attended applications"),
            ("reject_application", "Can reject applications"),
            ("force_status", "Can force status application"),
        )


VOTES = (
    (1, 'Positive'),
    (-1, 'Negative'),
    (0, 'Skipped'),
)


class Vote(models.Model):
    application = models.ForeignKey(Application)
    user = models.ForeignKey(admin_models.User)
    vote = models.IntegerField(choices=VOTES)

    class Meta:
        unique_together = ('application', 'user')

@@ -1644,25 +1644,16 @@
     def 
-positive_
 votes(se
@@ -1657,38 +1657,39 @@
 (self):%0A        
-return
+total =
  self.vote_set.f
@@ -1691,31 +1691,16 @@
 set.
-filter(vote=1).
 count()%0A
 %0A   
@@ -1699,61 +1699,40 @@
 t()%0A
-%0A
     
-@property%0A
     
-def negative_votes(self):%0A
+if not total:%0A  
         
 retu
@@ -1723,30 +1723,57 @@
 :%0A          
+  
 return
+ total%0A        positive =
  self.vote_s
@@ -1787,17 +1787,16 @@
 er(vote=
--
 1).count
@@ -1802,128 +1802,64 @@
 t()%0A
-%0A
     
-@property%0A    def votes(self):%0A        total = self.vote_set.count()%0A        if not total:%0A            return total
+    negative = self.vote_set.filter(vote=-1).count()
 %0A   
@@ -1874,21 +1874,16 @@
 urn 
-self.
 positive
 _vot
@@ -1882,31 +1882,20 @@
 tive
-_votes - (self.
+ - (
 negative
 _vot
@@ -1894,14 +1894,8 @@
 tive
-_votes
  * 3

refactor votes - removed positive votes property - removed negative votes property