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

[((520, 577), 'django.db.models.CharField', 'models.CharField', ([], {'max_length': '(256)', 'verbose_name': '"""Название"""'}), "(max_length=256, verbose_name='Название')\n", (536, 577), False, 'from django.db import models\n'), ((589, 663), 'django.db.models.SlugField', 'models.SlugField', ([], {'max_length': '(50)', 'unique': '(True)', 'verbose_name': '"""Идентификатор"""'}), "(max_length=50, unique=True, verbose_name='Идентификатор')\n", (605, 663), False, 'from django.db import models\n'), ((926, 983), 'django.db.models.CharField', 'models.CharField', ([], {'max_length': '(256)', 'verbose_name': '"""Название"""'}), "(max_length=256, verbose_name='Название')\n", (942, 983), False, 'from django.db import models\n'), ((995, 1069), 'django.db.models.SlugField', 'models.SlugField', ([], {'max_length': '(50)', 'unique': '(True)', 'verbose_name': '"""Идентификатор"""'}), "(max_length=50, unique=True, verbose_name='Идентификатор')\n", (1011, 1069), False, 'from django.db import models\n'), ((1329, 1370), 'django.db.models.TextField', 'models.TextField', ([], {'verbose_name': '"""Название"""'}), "(verbose_name='Название')\n", (1345, 1370), False, 'from django.db import models\n'), ((1382, 1457), 'django.db.models.IntegerField', 'models.IntegerField', ([], {'validators': '[validate_year]', 'verbose_name': '"""Год выпуска"""'}), "(validators=[validate_year], verbose_name='Год выпуска')\n", (1401, 1457), False, 'from django.db import models\n'), ((1493, 1546), 'django.db.models.TextField', 'models.TextField', ([], {'blank': '(True)', 'verbose_name': '"""Описание"""'}), "(blank=True, verbose_name='Описание')\n", (1509, 1546), False, 'from django.db import models\n'), ((1576, 1649), 'django.db.models.ManyToManyField', 'models.ManyToManyField', (['Genre'], {'through': '"""GenreTitle"""', 'verbose_name': '"""Жанры"""'}), "(Genre, through='GenreTitle', verbose_name='Жанры')\n", (1598, 1649), False, 'from django.db import models\n'), ((1690, 1821), 'django.db.models.ForeignKey', 'models.ForeignKey', (['Category'], {'on_delete': 'models.SET_NULL', 'blank': '(True)', 'null': '(True)', 'related_name': '"""titles"""', 'verbose_name': '"""Категория"""'}), "(Category, on_delete=models.SET_NULL, blank=True, null=\n    True, related_name='titles', verbose_name='Категория')\n", (1707, 1821), False, 'from django.db import models\n'), ((2240, 2314), 'django.db.models.ForeignKey', 'models.ForeignKey', (['Genre'], {'on_delete': 'models.SET_NULL', 'blank': '(True)', 'null': '(True)'}), '(Genre, on_delete=models.SET_NULL, blank=True, null=True)\n', (2257, 2314), False, 'from django.db import models\n'), ((2360, 2410), 'django.db.models.ForeignKey', 'models.ForeignKey', (['Title'], {'on_delete': 'models.CASCADE'}), '(Title, on_delete=models.CASCADE)\n', (2377, 2410), False, 'from django.db import models\n'), ((2527, 2606), 'django.db.models.ForeignKey', 'models.ForeignKey', (['Title'], {'on_delete': 'models.CASCADE', 'verbose_name': '"""Произведение"""'}), "(Title, on_delete=models.CASCADE, verbose_name='Произведение')\n", (2544, 2606), False, 'from django.db import models\n'), ((2649, 2687), 'django.db.models.TextField', 'models.TextField', ([], {'verbose_name': '"""текст"""'}), "(verbose_name='текст')\n", (2665, 2687), False, 'from django.db import models\n'), ((2716, 2793), 'django.db.models.ForeignKey', 'models.ForeignKey', (['CustomUser'], {'on_delete': 'models.CASCADE', 'verbose_name': '"""Автор"""'}), "(CustomUser, on_delete=models.CASCADE, verbose_name='Автор')\n", (2733, 2793), False, 'from django.db import models\n'), ((3008, 3079), 'django.db.models.DateTimeField', 'models.DateTimeField', ([], {'auto_now_add': '(True)', 'verbose_name': '"""Дата публикации"""'}), "(auto_now_add=True, verbose_name='Дата публикации')\n", (3028, 3079), False, 'from django.db import models\n'), ((3494, 3596), 'django.db.models.ForeignKey', 'models.ForeignKey', (['Review'], {'on_delete': 'models.CASCADE', 'related_name': '"""comments"""', 'verbose_name': '"""Отзыв"""'}), "(Review, on_delete=models.CASCADE, related_name='comments',\n    verbose_name='Отзыв')\n", (3511, 3596), False, 'from django.db import models\n'), ((3643, 3681), 'django.db.models.TextField', 'models.TextField', ([], {'verbose_name': '"""Текст"""'}), "(verbose_name='Текст')\n", (3659, 3681), False, 'from django.db import models\n'), ((3695, 3802), 'django.db.models.ForeignKey', 'models.ForeignKey', (['CustomUser'], {'on_delete': 'models.CASCADE', 'related_name': '"""comments"""', 'verbose_name': '"""Автор"""'}), "(CustomUser, on_delete=models.CASCADE, related_name=\n    'comments', verbose_name='Автор')\n", (3712, 3802), False, 'from django.db import models\n'), ((3851, 3922), 'django.db.models.DateTimeField', 'models.DateTimeField', ([], {'auto_now_add': '(True)', 'verbose_name': '"""Дата публикации"""'}), "(auto_now_add=True, verbose_name='Дата публикации')\n", (3871, 3922), False, 'from django.db import models\n'), ((369, 418), 'django.core.exceptions.ValidationError', 'ValidationError', (['"""Год выпуска превышает текущий!"""'], {}), "('Год выпуска превышает текущий!')\n", (384, 418), False, 'from django.core.exceptions import ValidationError\n'), ((331, 348), 'datetime.datetime.now', 'dt.datetime.now', ([], {}), '()\n', (346, 348), True, 'import datetime as dt\n'), ((3155, 3228), 'django.db.models.UniqueConstraint', 'models.UniqueConstraint', ([], {'fields': "['author', 'title']", 'name': '"""unique review"""'}), "(fields=['author', 'title'], name='unique review')\n", (3178, 3228), False, 'from django.db import models\n'), ((2890, 2910), 'django.core.validators.MinValueValidator', 'MinValueValidator', (['(1)'], {}), '(1)\n', (2907, 2910), False, 'from django.core.validators import MinValueValidator, MaxValueValidator\n'), ((2924, 2945), 'django.core.validators.MaxValueValidator', 'MaxValueValidator', (['(10)'], {}), '(10)\n', (2941, 2945), False, 'from django.core.validators import MinValueValidator, MaxValueValidator\n')]