import datetime as dt

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.core.exceptions import ValidationError

from users.models import CustomUser


def validate_year(value):
    """
    Год выпуска произведения не может быть больше текущего.
    """
    if value > dt.datetime.now().year:
        raise ValidationError(
            'Год выпуска превышает текущий!')
    return value


class Category(models.Model):
    """Модель категорий."""
    name = models.CharField(max_length=256, verbose_name='Название')
    slug = models.SlugField(
        max_length=50,
        unique=True,
        verbose_name='Идентификатор')

    class Meta:
        ordering = ('name',)
        verbose_name = 'Категория'
        verbose_name_plural = 'Категории'

    def __str__(self):
        return self.slug


class Genre(models.Model):
    """Модель жанров."""
    name = models.CharField(max_length=256, verbose_name='Название')
    slug = models.SlugField(
        max_length=50,
        unique=True,
        verbose_name='Идентификатор')

    class Meta:
        ordering = ('name',)
        verbose_name = 'Жанр'
        verbose_name_plural = 'Жанры'

    def __str__(self):
        return self.slug


class Title(models.Model):
    """Модель произведений."""
    name = models.TextField(verbose_name='Название')
    year = models.IntegerField(
        validators=[validate_year],
        verbose_name='Год выпуска')
    description = models.TextField(
        blank=True,
        verbose_name='Описание')
    genre = models.ManyToManyField(
        Genre,
        through='GenreTitle',
        verbose_name='Жанры')
    category = models.ForeignKey(
        Category,
        on_delete=models.SET_NULL,
        blank=True,
        null=True,
        related_name='titles',
        verbose_name='Категория')

    class Meta:
        ordering = ('name',)
        verbose_name = 'Произведение'
        verbose_name_plural = 'Произведения'

    def __str__(self):
        return (
            f'name: {self.name}, '
            f'year: {self.year}, '
        )


class GenreTitle(models.Model):
    """Модель для связи произведений и жанров отношением многие ко многим."""
    genre = models.ForeignKey(
        Genre,
        on_delete=models.SET_NULL,
        blank=True,
        null=True)
    title = models.ForeignKey(Title, on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.genre}  ---  {self.title}'


class Review(models.Model):
    title = models.ForeignKey(
        Title,
        on_delete=models.CASCADE,
        verbose_name='Произведение',
    )
    text = models.TextField(
        verbose_name='текст',
    )
    author = models.ForeignKey(
        CustomUser,
        on_delete=models.CASCADE,
        verbose_name='Автор'
    )
    score = models.IntegerField(
        validators=[
            MinValueValidator(1),
            MaxValueValidator(10)
        ],
        verbose_name='Оценка'
    )
    pub_date = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата публикации'
    )

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['author', 'title'],
                name='unique review'
            )
        ]
        verbose_name = 'Отзыв'
        verbose_name_plural = 'Отзывы'
        default_related_name = 'reviews'

    def __str__(self):
        return self.text[:60]


class Comment(models.Model):
    review = models.ForeignKey(
        Review,
        on_delete=models.CASCADE,
        related_name='comments',
        verbose_name='Отзыв',
    )
    text = models.TextField(verbose_name='Текст')
    author = models.ForeignKey(
        CustomUser,
        on_delete=models.CASCADE,
        related_name='comments',
        verbose_name='Автор'
    )
    pub_date = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата публикации'
    )

    class Meta:
        verbose_name = 'Комментарий'
        verbose_name_plural = 'Комментарии'

    def __str__(self):
        return self.text

[((22, 11, 22, 76), 'django.db.models.CharField', 'models.CharField', (), '', False, 'from django.db import models\n'), ((23, 11, 26, 50), 'django.db.models.SlugField', 'models.SlugField', (), '', False, 'from django.db import models\n'), ((39, 11, 39, 76), 'django.db.models.CharField', 'models.CharField', (), '', False, 'from django.db import models\n'), ((40, 11, 43, 50), 'django.db.models.SlugField', 'models.SlugField', (), '', False, 'from django.db import models\n'), ((56, 11, 56, 60), 'django.db.models.TextField', 'models.TextField', (), '', False, 'from django.db import models\n'), ((57, 11, 59, 45), 'django.db.models.IntegerField', 'models.IntegerField', (), '', False, 'from django.db import models\n'), ((60, 18, 62, 40), 'django.db.models.TextField', 'models.TextField', (), '', False, 'from django.db import models\n'), ((63, 12, 66, 34), 'django.db.models.ManyToManyField', 'models.ManyToManyField', (), '', False, 'from django.db import models\n'), ((67, 15, 73, 42), 'django.db.models.ForeignKey', 'models.ForeignKey', (), '', False, 'from django.db import models\n'), ((89, 12, 93, 18), 'django.db.models.ForeignKey', 'models.ForeignKey', (), '', False, 'from django.db import models\n'), ((94, 12, 94, 62), 'django.db.models.ForeignKey', 'models.ForeignKey', (), '', False, 'from django.db import models\n'), ((101, 12, 105, 5), 'django.db.models.ForeignKey', 'models.ForeignKey', (), '', False, 'from django.db import models\n'), ((106, 11, 108, 5), 'django.db.models.TextField', 'models.TextField', (), '', False, 'from django.db import models\n'), ((109, 13, 113, 5), 'django.db.models.ForeignKey', 'models.ForeignKey', (), '', False, 'from django.db import models\n'), ((121, 15, 124, 5), 'django.db.models.DateTimeField', 'models.DateTimeField', (), '', False, 'from django.db import models\n'), ((142, 13, 147, 5), 'django.db.models.ForeignKey', 'models.ForeignKey', (), '', False, 'from django.db import models\n'), ((148, 11, 148, 54), 'django.db.models.TextField', 'models.TextField', (), '', False, 'from django.db import models\n'), ((149, 13, 154, 5), 'django.db.models.ForeignKey', 'models.ForeignKey', (), '', False, 'from django.db import models\n'), ((155, 15, 158, 5), 'django.db.models.DateTimeField', 'models.DateTimeField', (), '', False, 'from django.db import models\n'), ((15, 14, 16, 71), 'django.core.exceptions.ValidationError', 'ValidationError', ({(16, 12, 16, 70): '"""Год выпуска превышает текущий!"""'}, {}), "('Год выпуска превышает текущий!')", False, 'from django.core.exceptions import ValidationError\n'), ((14, 15, 14, 32), 'datetime.datetime.now', 'dt.datetime.now', ({}, {}), '()', True, 'import datetime as dt\n'), ((128, 12, 131, 13), 'django.db.models.UniqueConstraint', 'models.UniqueConstraint', (), '', False, 'from django.db import models\n'), ((116, 12, 116, 32), 'django.core.validators.MinValueValidator', 'MinValueValidator', ({(116, 30, 116, 31): '1'}, {}), '(1)', False, 'from django.core.validators import MinValueValidator, MaxValueValidator\n'), ((117, 12, 117, 33), 'django.core.validators.MaxValueValidator', 'MaxValueValidator', ({(117, 30, 117, 32): '10'}, {}), '(10)', False, 'from django.core.validators import MinValueValidator, MaxValueValidator\n')]