"""Review app models."""
from pprint import pprint

from django.contrib.contenttypes import fields as generic
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from django.db.models.signals import post_init, post_save
from django.dispatch import receiver
from django.utils.translation import gettext_lazy as _

from utils.models import (BaseAttributes, TranslatedFieldsMixin,
                          ProjectBaseMixin, GalleryMixin,
                          TJSONField, IntermediateGalleryModelMixin)


class ReviewQuerySet(models.QuerySet):
    """QuerySets for model Review"""

    def by_reviewer(self, user):
        """Return reviews by user"""
        return self.filter(reviewer=user)

    def by_vintage(self, year: int):
        """Return reviews by year"""
        return self.filter(vintage=year)

    def by_status(self, status):
        """Filter by status"""
        return self.filter(status=status)

    def published(self):
        """Return published reviews"""
        return self.filter(status=Review.READY)


class Review(BaseAttributes, TranslatedFieldsMixin):
    """Review model"""
    TO_INVESTIGATE = 0
    TO_REVIEW = 1
    READY = 2
    REVIEW_STATUSES = (
        (TO_INVESTIGATE, _('To investigate')),
        (TO_REVIEW, _('To review')),
        (READY, _('Ready')),
    )
    reviewer = models.ForeignKey(
        'account.User',
        related_name='reviews',
        on_delete=models.CASCADE,
        verbose_name=_('Reviewer'),
        null=True, default=None, blank=True
    )
    country = models.ForeignKey(
        'location.Country',
        on_delete=models.CASCADE,
        related_name='country',
        verbose_name=_('Country'),
        null=True,
    )
    child = models.ForeignKey(
        'self',
        blank=True,
        default=None,
        null=True,
        on_delete=models.CASCADE,
        verbose_name=_('Child review'),
    )
    text = TJSONField(
        _('text'),
        null=True,
        blank=True,
        default=None,
        help_text='{"en-GB":"Text review"}',
    )
    content_type = models.ForeignKey(generic.ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

    status = models.PositiveSmallIntegerField(choices=REVIEW_STATUSES, default=TO_INVESTIGATE)
    published_at = models.DateTimeField(
        _('Publish datetime'),
        blank=True,
        default=None,
        null=True,
        help_text=_('Review published datetime'),
    )
    vintage = models.IntegerField(_('Year of review'), validators=[MinValueValidator(1900), MaxValueValidator(2100)])
    mark = models.FloatField(verbose_name=_('mark'), blank=True, null=True, default=None)
    priority = models.PositiveSmallIntegerField(_('Priority'), blank=True, null=True, default=None)
    old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)

    objects = ReviewQuerySet.as_manager()

    class Meta:
        """Meta class."""
        verbose_name = _('Review')
        verbose_name_plural = _('Reviews')


class ReviewTextAuthor(ProjectBaseMixin):
    author = models.ForeignKey(
        'account.User',
        verbose_name=_('author'),
        on_delete=models.CASCADE,
        related_name='review_authors',
    )
    review = models.ForeignKey(
        'review.Review',
        verbose_name=_('review'),
        on_delete=models.CASCADE,
        related_name='text_authors',
    )
    locale = models.CharField(_('locale'), max_length=10)

    class Meta:
        verbose_name = _('Text author')
        verbose_name_plural = _('Text authors')
        unique_together = ('locale', 'review')


class Inquiries(GalleryMixin, ProjectBaseMixin):
    NONE = 0
    DINER = 1
    LUNCH = 2
    MOMENTS = (
        (NONE, _('none')),
        (DINER, _('diner')),
        (LUNCH, _('lanch')),
    )
    old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
    review = models.ForeignKey(Review, verbose_name=_('review'), related_name='inquiries', on_delete=models.CASCADE)
    comment = models.TextField(_('comment'), blank=True, null=True)
    final_comment = models.TextField(_('final comment'), blank=True, null=True)
    mark = models.FloatField(verbose_name=_('mark'), blank=True, null=True, default=None)
    attachment_file = models.URLField(verbose_name=_('attachment'), max_length=255, blank=True, null=True, default=None)
    attachment_content_type = models.CharField(max_length=255, blank=True, null=True)
    author = models.ForeignKey('account.User', related_name='incuiries', on_delete=models.CASCADE,
                               verbose_name=_('author'))
    bill_file = models.URLField(verbose_name=_('bill'), max_length=255, blank=True, null=True, default=None)
    bill_content_type = models.CharField(max_length=255, blank=True, null=True)
    price = models.DecimalField(_('price'), max_digits=7, decimal_places=2, blank=True, null=True)
    moment = models.PositiveSmallIntegerField(choices=MOMENTS, default=NONE)
    gallery = models.ManyToManyField('gallery.Image', through='review.InquiriesGallery')
    decibels = models.CharField(max_length=255, blank=True, null=True)
    nomination = models.CharField(max_length=255, blank=True, null=True)
    nominee = models.CharField(max_length=255, blank=True, null=True)
    published = models.BooleanField(_('is published'), default=False)

    class Meta:
        verbose_name = _('Inquiry')
        verbose_name_plural = _('Inquiries')

    def __str__(self):
        return f'id: {self.id}, review: {self.review.id}, author: {self.author.id}'


class GridItems(ProjectBaseMixin):
    old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
    inquiry = models.ForeignKey(Inquiries, verbose_name=_('inquiry'), on_delete=models.CASCADE, related_name='grids')
    sub_name = models.CharField(_('sub name'), max_length=255, blank=True, null=True)
    name = models.CharField(_('name'), max_length=255, blank=True, null=True)
    value = models.FloatField(_('value'), blank=True, null=True)
    desc = models.TextField(_('description'), blank=True, null=True)
    dish_title = models.CharField(_('dish title'), max_length=255, blank=True, null=True)

    class Meta:
        verbose_name = _('inquiry grid')
        verbose_name_plural = _('inquiry grids')

    def __str__(self):
        return f'inquiry: {self.inquiry.id}, grid id: {self.id}'


class InquiriesGallery(IntermediateGalleryModelMixin):
    old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
    inquiry = models.ForeignKey(
        Inquiries,
        null=True,
        related_name='inquiries_gallery',
        on_delete=models.CASCADE,
        verbose_name=_('inquiry'),
    )
    image = models.ForeignKey(
        'gallery.Image',
        null=True,
        related_name='inquiries_gallery',
        on_delete=models.CASCADE,
        verbose_name=_('image'),
    )

    class Meta:
        verbose_name = _('inquiry gallery')
        verbose_name_plural = _('inquiry galleries')
