from django.db import models
from django.utils.translation import gettext_lazy as _
from datetime import time, datetime

from utils.models import ProjectBaseMixin


class Timetable(ProjectBaseMixin):
    """Timetable model."""
    MONDAY = 0
    TUESDAY = 1
    WEDNESDAY = 2
    THURSDAY = 3
    FRIDAY = 4
    SATURDAY = 5
    SUNDAY = 6

    NOON = time(17, 0)

    WEEKDAYS_CHOICES = (
        (MONDAY, _('Monday')),
        (TUESDAY, _('Tuesday')),
        (WEDNESDAY, _('Wednesday')),
        (THURSDAY, _('Thursday')),
        (FRIDAY, _('Friday')),
        (SATURDAY, _('Saturday')),
        (SUNDAY, _('Sunday')))

    weekday = models.PositiveSmallIntegerField(choices=WEEKDAYS_CHOICES, verbose_name=_('Week day'))

    lunch_start = models.TimeField(verbose_name=_('Lunch start time'), null=True)
    lunch_end = models.TimeField(verbose_name=_('Lunch end time'), null=True)
    dinner_start = models.TimeField(verbose_name=_('Dinner start time'), null=True)
    dinner_end = models.TimeField(verbose_name=_('Dinner end time'), null=True)
    opening_at = models.TimeField(verbose_name=_('Opening time'), null=True)
    closed_at = models.TimeField(verbose_name=_('Closed time'), null=True)

    class Meta:
        """Meta class."""
        verbose_name = _('Timetable')
        verbose_name_plural = _('Timetables')
        ordering = ['weekday']

    def __str__(self):
        """Overridden str dunder."""
        return f'{self.get_weekday_display()} ' \
               f'(closed_at - {self.closed_at_str}, ' \
               f'opening_at - {self.opening_at_str}, ' \
               f'opening_time - {self.opening_time}, ' \
               f'ending_time - {self.ending_time}, ' \
               f'works_at_noon - {self.works_at_noon}, ' \
               f'works_at_afternoon: {self.works_at_afternoon})'

    @property
    def closed_at_str(self):
        return str(self.closed_at) if self.closed_at else None

    @property
    def opening_at_str(self):
        return str(self.opening_at) if self.opening_at else None

    @property
    def closed_at_indexing(self):
        return datetime.combine(time=self.closed_at, date=datetime(1970, 1, 1 + self.weekday).date()) if self.closed_at else None

    @property
    def opening_at_indexing(self):
        return datetime.combine(time=self.opening_at, date=datetime(1970, 1, 1 + self.weekday).date()) if self.opening_at else None

    @property
    def opening_time(self):
        return self.opening_at or self.lunch_start or self.dinner_start

    @property
    def ending_time(self):
        return self.closed_at or self.dinner_end or self.lunch_end

    @property
    def works_at_noon(self):
        return bool(self.opening_time and self.opening_time <= self.NOON)

    @property
    def works_at_afternoon(self):
        return bool(self.ending_time and self.ending_time > self.NOON)
