from django.db import models
from django.utils import timezone

RISK_CHOICES = (
    ('LOW', 'Low Risk'),
    ('MED', 'Medium Risk'),
    ('HIGH', 'High Risk'),
)


class Page(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField()
    unit = models.ForeignKey('units.Unit')
    order = models.IntegerField()
    theme = models.ForeignKey('Theme', blank=True, null=True)
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['order']

    def __unicode__(self):
        return self.title

    def get_self_assessments(self):
        return SelfAssessment.objects.filter(page=self)

    def get_incomplete_self_assessments(self, page_submission):
        completed_self_assessments_ids = SelfAssessmentSubmission.objects.filter(
            page_submission=page_submission,
        ).values_list('self_assessment__id', flat=True)

        self_assessments = SelfAssessment.objects.filter(page=self).exclude(
            id__in=completed_self_assessments_ids
        )

        return self_assessments

    def self_assessments_all_correct(self, page_submission):
        correct_self_assessments = SelfAssessmentSubmission.objects.filter(
            page_submission=page_submission,
            correct=True
        )

        if correct_self_assessments.count() == self.get_self_assessments().count():
            return True
        return False

    def get_self_assessment(self, id):
        try:
            return SelfAssessment.objects.get(page=self, id=id)
        except Exception:
            return None

    def get_next_self_assessment(self, page_submission):
        return self.get_incomplete_self_assessments(page_submission).first()

    def get_self_assessment_submissions(self, page_submission):
        return SelfAssessmentSubmission.objects.filter(page_submission=page_submission)

    def get_page_type(self):
        try:
            page_type = PageStatic.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = Page360Selection.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = Page360.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageMovement.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageDragDrop.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageDragDropRepeat.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageDragDropFillBox.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageDragDropColumns.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageDragDropColumnsEvaluate.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageCorrectEquipment.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageRateActivity.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        try:
            page_type = PageRateActivitySummary.objects.get(page=self)
            return page_type.__unicode__()
        except Exception:
            pass

        if SelfAssessment.objects.filter(page=self).count() > 0:
            return "Self Assessment"

        return False

    def get_content(self):
        try:
            page_type = PageStatic.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = Page360Selection.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = Page360.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageMovement.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageDragDrop.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageDragDropRepeat.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageDragDropFillBox.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageDragDropColumns.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageDragDropColumnsEvaluate.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageCorrectEquipment.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageRateActivity.objects.get(page=self)
            return page_type
        except Exception:
            pass

        try:
            page_type = PageRateActivitySummary.objects.get(page=self)
            return page_type
        except Exception:
            pass

        return False


class PageSubmission(models.Model):
    page = models.ForeignKey('Page')
    learner = models.ForeignKey('companies.Learner')
    unit_submission = models.ForeignKey('units.UnitSubmission')
    start_time = models.DateTimeField(auto_now_add=True)
    end_time = models.DateTimeField(blank=True, null=True)
    passed = models.BooleanField(default=False)
    duration = models.IntegerField(blank=True, null=True)

    def __unicode__(self):
        # return "Oh no"
        # return "%s" % (self.learner)
        return "%s %s" % (self.page, self.learner)

    def get_pano_submission(self):
        return Page360Submission.objects.get(page_submission=self)

    class Meta:
        ordering = ['page']

    def complete(self):
        if not self.end_time:
            self.end_time = timezone.now()
        self.passed = True
        self.save(update_fields=['end_time', 'passed'])


class Theme(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField()
    html = models.TextField()
    css = models.TextField()
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['title']

    def __unicode__(self):
        return self.title


class SelfAssessment(models.Model):

    page = models.ForeignKey('Page')
    question = models.TextField()
    options = models.TextField()
    answer = models.TextField()
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['id']

    def __unicode__(self):
        return self.question

    def get_option_list(self):
        return self.options.split(',')

    def get_submission(self):
        return SelfAssessmentSubmission.objects.get(self_assessment=self)

    def get_submissions(self):
        return SelfAssessmentSubmission.objects.filter(self_assessment=self)


class SelfAssessmentSubmission(models.Model):
    page_submission = models.ForeignKey('PageSubmission')
    self_assessment = models.ForeignKey('SelfAssessment')
    answer = models.TextField()
    correct = models.BooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return "%s" % (self.self_assessment)


# Page Types

class PageStatic(models.Model):
    page = models.ForeignKey('Page')
    content = models.TextField()
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    audio_file = models.FileField(upload_to='pages/static/audio', blank=True)

    def __unicode__(self):
        return "Static"


class Page360Selection(models.Model):
    page = models.ForeignKey('Page')
    page_360 = models.ForeignKey('pages.Page360')

    def __unicode__(self):
        return "360Selection"

    def get_360s(self):
        return self.page_360.panorama.all()


class Panorama(models.Model):
    title = models.CharField(max_length=100)
    path = models.CharField(max_length=100)
    thumbnail = models.ImageField(upload_to="pages/panos")

    def __unicode__(self):
        return self.title


class Page360(models.Model):
    page = models.ForeignKey('pages.Page')
    panorama = models.ManyToManyField('pages.Panorama')

    def __unicode__(self):
        return "360"


class Page360Submission(models.Model):
    pano_page = models.ForeignKey('pages.Page360')
    pano = models.ForeignKey('pages.Panorama')
    page_submission = models.ForeignKey('PageSubmission')
    start_time = models.DateTimeField(auto_now_add=True)
    end_time = models.DateTimeField(blank=True, null=True)
    completed = models.BooleanField(default=False)

    def get_hazard_count(self):
        return Hotspot.objects.filter(pano=self.pano, hazard=True).count()

    def get_spotted_count(self):
        spotted = HotspotSubmission.objects.filter(pano_submission=self, hotspot__pano=self.pano, hotspot__hazard=True).exclude(rating__exact="")
        if not spotted:
            return 0
        return spotted.count()

    def get_remaining_count(self):
        hazards = Hotspot.objects.filter(pano=self.pano)
        found = self.get_spotted_count()
        if not found:
            found = 0
        return hazards.count() - found

    def get_spotted_percentage(self):
        hazard_count = self.get_hazard_count()
        spotted = self.get_spotted_count()

        return float(spotted) / float(hazard_count) * 100


class ManagerPage360Submission(models.Model):
    pano_page = models.ForeignKey('pages.Page360')
    pano = models.ForeignKey('pages.Panorama')
    manager = models.ForeignKey('companies.CompanyManager')
    start_time = models.DateTimeField(auto_now_add=True)
    end_time = models.DateTimeField(blank=True, null=True)
    completed = models.BooleanField(default=False)

    def get_hazard_count(self):
        return Hotspot.objects.filter(pano=self.pano, hazard=True).count()

    def get_spotted_count(self):
        spotted = ManagerHotspotSubmission.objects.filter(
            pano_submission=self,
            hotspot__pano=self.pano,
            hotspot__hazard=True
        ).exclude(rating__exact="")
        if not spotted:
            return 0
        return spotted.count()

    def get_remaining_count(self):
        hazards = Hotspot.objects.filter(pano=self.pano)
        found = self.get_spotted_count()
        if not found:
            found = 0
        return hazards.count() - found

    def get_spotted_percentage(self):
        hazard_count = self.get_hazard_count()
        spotted = self.get_spotted_count()

        return float(spotted) / float(hazard_count) * 100


class Hotspot(models.Model):
    pano = models.ForeignKey('Panorama')
    title = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    score_board = models.CharField(max_length=100)
    hazard = models.BooleanField(default=True)
    identifier = models.CharField(max_length=20)
    hazard_image = models.ImageField(upload_to="hotspots", blank=True)
    liklihood = models.IntegerField()
    severity = models.IntegerField()
    rating = models.CharField(max_length=10, choices=RISK_CHOICES)

    def __unicode__(self):
        return self.title


class HotspotSubmission(models.Model):
    hotspot = models.ForeignKey('Hotspot')
    pano_submission = models.ForeignKey('Page360Submission')
    panorama = models.ForeignKey('Panorama')
    liklihood = models.IntegerField(default=1)
    severity = models.IntegerField(default=1)
    rating = models.CharField(max_length=10, choices=RISK_CHOICES)
    correct = models.BooleanField(default=False)


class ManagerHotspotSubmission(models.Model):
    hotspot = models.ForeignKey('Hotspot')
    pano_submission = models.ForeignKey('ManagerPage360Submission')
    panorama = models.ForeignKey('Panorama')
    liklihood = models.IntegerField(default=1)
    severity = models.IntegerField(default=1)
    rating = models.CharField(max_length=10, choices=RISK_CHOICES)
    correct = models.BooleanField(default=False)


class PageDragDrop(models.Model):
    page = models.ForeignKey('Page')
    custom_css = models.TextField(blank=True)
    html_above = models.TextField(blank=True)
    html_below = models.TextField(blank=True)

    def __unicode__(self):
        return "drag-drop"

    def get_draggables(self):
        return DragDropDraggable.objects.filter(drag_drop=self)

    def get_targets(self):
        return DragDropTarget.objects.filter(drag_drop=self)


class DragDropDraggable(models.Model):
    drag_drop = models.ForeignKey('PageDragDrop')
    order = models.IntegerField()
    image = models.ImageField(upload_to="pages/dragdrop")
    title = models.CharField(max_length=50, blank=True)

    def __unicode__(self):
        return "%d %s" % (self.order, self.image.name)

    class Meta:
        ordering = ['order']


class DragDropTarget(models.Model):
    drag_drop = models.ForeignKey('PageDragDrop')
    draggable = models.ManyToManyField('DragDropDraggable')
    order = models.IntegerField()
    image = models.ImageField(upload_to="pages/dragdrop")

    def __unicode__(self):
        return "%s - Order: %d, Draggable: %s" % (self.drag_drop.page, self.order, self.draggable)

    class Meta:
        ordering = ['order']


class PageDragDropRepeat(models.Model):
    page = models.ForeignKey('Page')
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    custom_css = models.TextField(blank=True)
    html_above = models.TextField(blank=True)
    html_below = models.TextField(blank=True)

    def __unicode__(self):
        return "drag-drop-repeat"

    def get_draggables(self):
        return DragDropRepeatDraggable.objects.filter(drag_drop=self)

    def get_targets(self):
        return DragDropRepeatTarget.objects.filter(drag_drop=self)


class DragDropRepeatDraggable(models.Model):
    drag_drop = models.ForeignKey('PageDragDropRepeat')
    order = models.IntegerField()
    image = models.ImageField(upload_to="pages/dragdroprepeat")

    def __unicode__(self):
        return "%s - %s - Order: %d, Image:%s" % (self.drag_drop.page, self.drag_drop, self.order, self.image)

    class Meta:
        ordering = ['order']


class DragDropRepeatTarget(models.Model):
    drag_drop = models.ForeignKey('PageDragDropRepeat')
    draggable = models.ForeignKey('DragDropRepeatDraggable')
    order = models.IntegerField()
    pre_image = models.ImageField(upload_to="pages/dragdroprepeat")
    post_image = models.ImageField(upload_to="pages/dragdroprepeat")

    def __unicode__(self):
        return "%s - Order: %d, Draggable: %s" % (self.drag_drop.page, self.order, self.draggable)

    class Meta:
        ordering = ['order']


class PageDragDropColumns(models.Model):
    page = models.ForeignKey('Page')
    title = models.ImageField(upload_to='pages/columns/title', blank=True)
    html_above = models.TextField(blank=True)

    def __unicode__(self):
        return "drag-drop-columns"

    def get_columns(self):
        return PageDragDropColumn.objects.filter(drag_drop=self)

    def get_draggables(self):
        return PageDragDropColumnDraggable.objects.filter(column__drag_drop=self)


class PageDragDropColumn(models.Model):
    drag_drop = models.ForeignKey('pages.PageDragDropColumns')
    title = models.CharField(max_length=100)
    sub_title = models.CharField(max_length=100, blank=True)
    spaces = models.IntegerField(default=4)
    order = models.IntegerField()

    def __unicode__(self):
        return "%s > %s > %s" % (self.drag_drop.page.unit, self.drag_drop.page, self.title)

    class Meta:
        ordering = ['order']

    def get_draggables(self):
        return PageDragDropColumnDraggable.objects.filter(column=self)


class PageDragDropColumnDraggable(models.Model):
    column = models.ForeignKey('pages.PageDragDropColumn')
    text = models.TextField()
    explanation = models.TextField(blank=True)
    order = models.IntegerField()

    def __unicode__(self):
        return self.text

    class Meta:
        ordering = ['order']


class PageDragDropColumnsEvaluate(models.Model):
    page = models.ForeignKey('Page')
    title = models.ImageField(upload_to='pages/columns/title')
    html_above = models.TextField(blank=True)

    def __unicode__(self):
        return "drag-drop-columns-evaluate"

    def get_columns(self):
        return PageDragDropColumnEvaluate.objects.filter(drag_drop=self)

    def get_draggables(self):
        return PageDragDropColumnEvaluateDraggable.objects.filter(drag_drop=self)


class PageDragDropColumnEvaluate(models.Model):
    drag_drop = models.ForeignKey('pages.PageDragDropColumnsEvaluate')
    title = models.CharField(max_length=100)
    sub_title = models.CharField(max_length=100, blank=True)
    order = models.IntegerField()
    none = models.TextField(blank=True)
    any = models.TextField(blank=True)
    all = models.TextField(blank=True)

    def __unicode__(self):
        return "%s > %s > %s" % (self.drag_drop.page.unit, self.drag_drop.page, self.title)

    class Meta:
        ordering = ['order']

    def get_draggables(self):
        return PageDragDropColumnDraggable.objects.filter(column=self)


class PageDragDropColumnEvaluateDraggable(models.Model):
    drag_drop = models.ForeignKey('pages.PageDragDropColumnsEvaluate')
    text = models.TextField()
    explanation = models.TextField(blank=True)
    order = models.IntegerField()

    def __unicode__(self):
        return self.text

    class Meta:
        ordering = ['order']


class PageDragDropFillBox(models.Model):
    page = models.ForeignKey('Page')
    title = models.ImageField(upload_to="pages/dragdropfillbox")
    image_of_box = models.ImageField(upload_to="pages/dragdropfillbox", blank=True)
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    html_above = models.TextField(blank=True)
    custom_css = models.TextField(blank=True)

    def __unicode__(self):
        return "drag-drop-fill-box"

    def get_draggables(self):
        return DragDropFillBoxDraggable.objects.filter(drag_drop=self)

    def get_targets(self):
        return DragDropFillBoxTarget.objects.filter(drag_drop=self)


class DragDropFillBoxDraggable(models.Model):
    drag_drop = models.ForeignKey('PageDragDropFillBox')
    order = models.IntegerField()
    title = models.TextField(blank=True)
    image = models.ImageField(upload_to="pages/dragdropfillbox")
    correct = models.BooleanField(default=False)

    def __unicode__(self):
        return "%s - Order: %d, Image:%s" % (self.drag_drop, self.order, self.image)

    class Meta:
        ordering = ['order']


class DragDropFillBoxTarget(models.Model):
    drag_drop = models.ForeignKey('PageDragDropFillBox')
    order = models.IntegerField()
    image = models.ImageField(upload_to="pages/dragdrop")

    def __unicode__(self):
        return "Order: %d, Draggable: %s" % (self.order, self.drag_drop)

    class Meta:
        ordering = ['order']


class PageMovement(models.Model):
    page = models.ForeignKey('Page')
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    audio = models.FileField(upload_to='audio', blank=True)

    def __unicode__(self):
        return "Movement"

    def get_frames(self):
        return PageMovementFrame.objects.filter(page_movement=self)

    def get_frame1(self):
        return PageMovementFrame.objects.filter(page_movement=self, frame_number='1')

    def get_frame2(self):
        return PageMovementFrame.objects.filter(page_movement=self, frame_number='2')

    def get_frame3(self):
        return PageMovementFrame.objects.filter(page_movement=self, frame_number='3')

    def get_frame4(self):
        return PageMovementFrame.objects.filter(page_movement=self, frame_number='4')

    def get_frame5(self):
        return PageMovementFrame.objects.filter(page_movement=self, frame_number='5')


class PageMovementFrame(models.Model):

    FRAME_CHOICES = (
        ('1', '1'),
        ('2', '2'),
        ('3', '3'),
        ('4', '4'),
        ('5', '5'),
    )
    order = models.IntegerField()
    page_movement = models.ForeignKey('PageMovement')
    frame_number = models.CharField(max_length=1, choices=FRAME_CHOICES)
    image = models.ImageField(upload_to="pages/movement")
    caption = models.TextField(blank=True)
    timing = models.IntegerField(default=6500)

    def __unicode__(self):
        return "%s - %s" % (self.page_movement.page, self.frame_number)

    class Meta:
        ordering = ['order']


class PageCorrectEquipment(models.Model):
    page = models.ForeignKey('Page')
    enabled = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    title = models.ImageField(upload_to='pages/equipment')
    person_using_equipment = models.ImageField(upload_to='pages/equipment')

    def __unicode__(self):
        return "correct-equipment"

    def get_hazards(self):
        return PageCorrectEquipmentHazard.objects.filter(correct_equipment=self)

    def get_equipment(self):
        return PageCorrectEquipmentItem.objects.filter(correct_equipment=self)


class PageCorrectEquipmentHazard(models.Model):
    title = models.CharField(max_length=100)
    correct_equipment = models.ForeignKey('pages.PageCorrectEquipment')
    hazard_image = models.ImageField(upload_to='pages/equipment')
    accepts = models.ManyToManyField('pages.PageCorrectEquipmentItem')
    success_image = models.ImageField(upload_to='pages/equipment')
    fail_image = models.ImageField(upload_to='pages/equipment')
    explanation = models.TextField()
    order = models.IntegerField()

    class Meta:
        ordering = ['order']

    def __unicode__(self):
        return self.title


class PageCorrectEquipmentItem(models.Model):
    title = models.CharField(max_length=100)
    correct_equipment = models.ForeignKey('pages.PageCorrectEquipment')
    order = models.IntegerField()
    small_image = models.ImageField(upload_to='pages/equipment')
    large_image = models.ImageField(upload_to='pages/equipment')

    class Meta:
        ordering = ['order']

    def __unicode__(self):
        return self.title


# RATE ACTIVITY

class RateActivity(models.Model):
    unit = models.ForeignKey('units.Unit')
    name = models.CharField(max_length=100, verbose_name="Rate Activity Name")

    class Meta:
        ordering = ['name']

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

    def get_options(self):
        return RateActivityOption.objects.filter(rate_activity=self)


class PageRateActivity(models.Model):
    activity = models.ForeignKey('pages.RateActivity')
    page = models.ForeignKey("pages.Page")
    html_above = models.TextField(blank=True)

    def __unicode__(self):
        return "rate"

    def get_questions(self):
        return RateActivityQuestion.objects.filter(rate_activity=self)


class RateActivityOption(models.Model):
    rate_activity = models.ForeignKey('pages.RateActivity')
    order = models.IntegerField()
    name = models.CharField(max_length=50)
    stars = models.IntegerField()
    description = models.TextField()

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['order']

    def get_stars(self):
        return [{}] * self.stars


class RateActivityQuestion(models.Model):
    rate_activity = models.ForeignKey('pages.PageRateActivity')
    order = models.IntegerField()
    description = models.TextField(verbose_name="Question")

    def __unicode__(self):
        return self.description


class RateActivityQuestionSubmission(models.Model):
    page_submission = models.ForeignKey('pages.PageSubmission')
    rate_activity_question = models.ForeignKey('pages.RateActivityQuestion')
    rate_activity_option = models.ForeignKey('pages.RateActivityOption')

    class Meta:
        ordering = ['page_submission__page__order', 'rate_activity_question__order']


class ManagerRateActivityQuestionSubmission(models.Model):
    manager = models.ForeignKey('companies.CompanyManager')
    page = models.ForeignKey('pages.Page')
    rate_activity_question = models.ForeignKey('pages.RateActivityQuestion')
    rate_activity_option = models.ForeignKey('pages.RateActivityOption')

    class Meta:
        ordering = ['page__order', 'rate_activity_question__order']


class PageRateActivitySummary(models.Model):
    page = models.ForeignKey("pages.Page")
    activity = models.ForeignKey('pages.RateActivity')

    def __unicode__(self):
        return "rate-results"


class Help(models.Model):
    page = models.ForeignKey('pages.Page', related_name="help")
    title = models.CharField(max_length=150)
    content = models.TextField(blank=True)
    published = models.BooleanField(default=True)

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = 'Help'
        verbose_name_plural = 'Help'

    def __unicode__(self):
        return self.title
