from django.db import models

from datetime import datetime,date,time
import os.path

from django.core.urlresolvers import reverse

class AbstractRequest(models.Model):

    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)
    description = models.TextField()

    enabled = models.BooleanField(default=True)
    start_date = models.DateField()
    end_date = models.DateField()

    member_types_allowed = models.ManyToManyField('members.MemberType',related_name='member_types_allowed_abstract_request',blank=True,verbose_name='Member Types Allowed to View (Leave Blank for Public access)')
    member_groups_allowed = models.ManyToManyField('members.MemberGroup',related_name='member_groups_allowed_abstract_request',blank=True,verbose_name='Member Groups Allowed to View (Leave Blank for Public access)')

    content_types = models.ManyToManyField('AbstractContentType',blank=False)
    categories = models.ManyToManyField('AbstractCategory',blank=False)

    def __unicode__(self):
        return self.name

    def get_status(self):

        today = date.today()

        if self.start_date > today:
            return 'pending'
        if self.start_date <= today and self.end_date >= today:
            return 'current'
        else:
            return 'ended'

    def get_submissions(self):
        submissions = AbstractSubmission.objects.filter(abstract_request=self,complete=True)
        return submissions

    def get_approved_submissions(self):
        submissions = AbstractSubmission.objects.filter(abstract_request=self,status='approved')
        return submissions

    def get_outstanding_reviews(self,member):
        outstanding_reviews = AbstractSubmissionReview.objects.filter(reviewer=member,content_submission__abstract_request=self,reviewed=False)
        return outstanding_reviews


class AbstractContentType(models.Model):

    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)
    code = models.CharField(max_length=10)
    order = models.IntegerField()

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['order']

    def get_submissions(self,abstract_request=False):
        if abstract_request:
            submissions = AbstractSubmission.objects.filter(abstract_request=abstract_request,content_type=self,complete=True)
        else :
            submissions = AbstractSubmission.objects.filter(content_type=self,complete=True)
        return submissions

class AbstractCategory(models.Model):

    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)
    order = models.IntegerField()

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['order']

class AbstractSubmission(models.Model):

    STATUS_CHOICES = (
        (u'pending',u'Pending'),
        (u'approved',u'Approved'),
        (u'rejected', u'Rejected'),
    )

    TITLE_CHOICES = (
        (u'Mr',u'Mr'),
        (u'Mrs',u'Mrs'),
        (u'Miss',u'Miss'),
        (u'Ms',u'Ms'),
        (u'Doctor',u'Doctor'),
        (u'Professor',u'Professor'),
    )

    abstract_request = models.ForeignKey('AbstractRequest')
    member = models.ForeignKey('members.Member',blank=True,null=True,related_name='Member')

    title = models.CharField(max_length=20,choices=TITLE_CHOICES)
    given_name = models.CharField(max_length=200)
    surname = models.CharField(max_length=200)
    email = models.EmailField()
    telephone = models.CharField(max_length=20)
    date_of_birth = models.DateField()

    content_type = models.ForeignKey('AbstractContentType',verbose_name='submission type')
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    first_save = models.BooleanField(default=True)
    complete = models.BooleanField(default=False)
    paid = models.BooleanField(default=False)
    member_registered = models.BooleanField(default=False)
    status = models.CharField(max_length=200,choices=STATUS_CHOICES,default='pending')
    unique_key = models.CharField(max_length=50,blank=True,null=True)
    unique_code = models.CharField(max_length=10,blank=True,null=True)

    num_authors = models.IntegerField(default=1)
    all_authors_notified = models.BooleanField(default=False)

    abstract_title = models.CharField(max_length=200,blank=True,null=True)
    abstract_category = models.ForeignKey('AbstractCategory',blank=True,null=True)
    presenter       = models.CharField(max_length=200,blank=True,null=True,verbose_name='Who will be presenting')
    abstract_content = models.TextField(blank=True,null=True)

    #billing address details
    address_1 = models.CharField(max_length=200,blank=True,null=True)
    address_2 = models.CharField(max_length=200,blank=True,null=True)
    town = models.CharField(max_length=200,blank=True,null=True)
    county = models.CharField(max_length=200,blank=True,null=True)
    country = models.ForeignKey('members.Country',related_name='abstract_country',blank=True,null=True)
    postcode = models.CharField(max_length=20,blank=True,null=True)

    #invoice fields
    invoice_company_name = models.CharField(max_length=200,blank=True,null=True,verbose_name='Company Name')
    invoice_email = models.EmailField(max_length=200,blank=True,null=True,verbose_name='Email Address')

    def __unicode__(self):
        return "%s %s - %s" % (self.given_name,self.surname,self.created)

    class Meta:
        ordering = ('content_type__order','abstract_category__order')

    def get_reviews(self):
        reviews = AbstractSubmissionReview.objects.filter(content_submission=self).order_by('-created')
        return reviews

    def get_files(self):
        files = AbstractSubmissionFile.objects.filter(content_submission=self).order_by('order')
        return files

    def get_next_file_order(self):
        files = self.get_files().reverse()
        if files:
            last_file = files[0]
            order = last_file.order + 1
            return order
        else:
            return 1

    def get_authors(self):
        authors = AbstractSubmissionAuthor.objects.filter(content_submission=self).order_by('order')
        return authors

    def get_next_author_order(self):
        authors = self.get_authors().reverse()
        if authors:
            last_author = authors[0]
            order = last_author.order + 1
            return order
        else:
            return 1

    def get_unique_code(self):

        z_fill = str(self.id).zfill(6)
        code = self.content_type.code

        return "%s%s" % (code,z_fill)

    def get_category(self):
        return self.abstract_category

    def get_score_average(self):
        return 0

    def get_name(self):
        return '{} {}'.format(self.given_name, self.surname)

    def get_title(self):
        return self.abstract_title

    def get_score_average(self):

        completed_reviews = AbstractSubmissionReview.objects.filter(content_submission=self,reviewed=True)

        if completed_reviews:
            count = completed_reviews.count()
            total = 0
            for completed_review in completed_reviews:
                total = total + completed_review.get_total()

            average = float(total) / float(count)
            return "%.2f" % (average)

        else:
            return 0


class AbstractSubmissionFile(models.Model):

    content_submission = models.ForeignKey('AbstractSubmission')
    file = models.FileField(upload_to='abstracts/submission')
    order = models.IntegerField()

    def __unicode__(self):
        return """%s - %s""" % (self.content_submission,self.filename())

    def filename(self):
        return os.path.basename(self.file.name)


class AbstractSubmissionAuthor(models.Model):

    GRADE_CHOICES = (
        (u'',u'Please Select'),
        (u'con',u'Consultant'),
        (u'gp',u'GP'),
        (u'vet',u'Veterinarian'),
        (u'reg',u'Registrar'),
        (u'doc',u'Doctor in training'),
        (u'con-son',u'Consultant Sonographer'),
        (u'son',u'Sonographer'),
        (u'rad',u'Radiographer'),
        (u'stu-son-rad',u'Student Sonographer / Radiographer'),
        (u'edu',u'Educationalist'),
        (u'ccs',u'Consultant Clinical Scientist'),
        (u'cli-sci',u'Clinical Scientist'),
        (u'phy',u'Physicist'),
        (u'aaa-tech',u'AAA Technician'),
        (u'vas-sci',u'Vascular Scientist'),
    )

    content_submission = models.ForeignKey('AbstractSubmission')
    name = models.CharField(max_length=200)
    status = models.CharField(max_length=200,choices=GRADE_CHOICES,default='',verbose_name='grade')
    institution = models.CharField(max_length=200)
    department = models.CharField(max_length=200)
    email = models.EmailField()
    telephone = models.CharField(max_length=20, verbose_name='contact number')
    order = models.IntegerField()

    def __unicode__(self):
        return "%s %s" % (self.name,self.content_submission)

class AbstractSubmissionReview(models.Model):

    content_submission = models.ForeignKey('AbstractSubmission')
    created = models.DateTimeField(auto_now_add=True)
    sent = models.BooleanField(default=False)

    reviewer = models.ForeignKey('members.Member',related_name='submission_reviewer')
    reviewed = models.BooleanField(default=False)
    review_created = models.DateTimeField(blank=True,null=True)

    scorer_name = models.CharField(max_length=200,blank=True,null=True)
    comment = models.TextField(blank=True,null=True,verbose_name='additional_comments')

    title_score = models.IntegerField(verbose_name="Title",default=0)
    abstract_construction = models.IntegerField(verbose_name='construction',default=0)
    content_score = models.IntegerField(verbose_name="Content",default=0)
    relevance_score = models.IntegerField(verbose_name="Relevance",default=0)
    priority_score = models.IntegerField(default=0)

    class Meta:
        ordering = ['content_submission','reviewer']

    def get_total(self):
        total = self.title_score + self.abstract_construction + self.content_score + self.relevance_score + self.priority_score
        return total

    def __unicode__(self):
        return "%s %s" % (self.content_submission,self.reviewer)

    def get_next(self):

        next_object = False
        objects = AbstractSubmissionReview.objects.filter(content_submission__abstract_request=self.content_submission.abstract_request,reviewer=self.reviewer,sent=True,reviewed=False)
        if objects:
            return objects[0]
        else:
            return False
