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, 'django.db.models.CharField', 'models.CharField', ([], {'max_length': '(256)', 'verbose_name': '"""Название"""'}), False, 'from django.db import models\n'), (23, 'django.db.models.SlugField', 'models.SlugField', ([], {'max_length': '(50)', 'unique': '(True)', 'verbose_name': '"""Идентификатор"""'}), False, 'from django.db import models\n'), (39, 'django.db.models.CharField', 'models.CharField', ([], {'max_length': '(256)', 'verbose_name': '"""Название"""'}), False, 'from django.db import models\n'), (40, 'django.db.models.SlugField', 'models.SlugField', ([], {'max_length': '(50)', 'unique': '(True)', 'verbose_name': '"""Идентификатор"""'}), False, 'from django.db import models\n'), (56, 'django.db.models.TextField', 'models.TextField', ([], {'verbose_name': '"""Название"""'}), False, 'from django.db import models\n'), (57, 'django.db.models.IntegerField', 'models.IntegerField', ([], {'validators': '[validate_year]', 'verbose_name': '"""Год выпуска"""'}), False, 'from django.db import models\n'), (60, 'django.db.models.TextField', 'models.TextField', ([], {'blank': '(True)', 'verbose_name': '"""Описание"""'}), False, 'from django.db import models\n'), (63, 'django.db.models.ManyToManyField', 'models.ManyToManyField', (['Genre'], {'through': '"""GenreTitle"""', 'verbose_name': '"""Жанры"""'}), False, 'from django.db import models\n'), (67, 'django.db.models.ForeignKey', 'models.ForeignKey', (['Category'], {'on_delete': 'models.SET_NULL', 'blank': '(True)', 'null': '(True)', 'related_name': '"""titles"""', 'verbose_name': '"""Категория"""'}), False, 'from django.db import models\n'), (89, 'django.db.models.ForeignKey', 'models.ForeignKey', (['Genre'], {'on_delete': 'models.SET_NULL', 'blank': '(True)', 'null': '(True)'}), False, 'from django.db import models\n'), (94, 'django.db.models.ForeignKey', 'models.ForeignKey', (['Title'], {'on_delete': 'models.CASCADE'}), False, 'from django.db import models\n'), (101, 'django.db.models.ForeignKey', 'models.ForeignKey', (['Title'], {'on_delete': 'models.CASCADE', 'verbose_name': '"""Произведение"""'}), False, 'from django.db import models\n'), (106, 'django.db.models.TextField', 'models.TextField', ([], {'verbose_name': '"""текст"""'}), False, 'from django.db import models\n'), (109, 'django.db.models.ForeignKey', 'models.ForeignKey', (['CustomUser'], {'on_delete': 'models.CASCADE', 'verbose_name': '"""Автор"""'}), False, 'from django.db import models\n'), (121, 'django.db.models.DateTimeField', 'models.DateTimeField', ([], {'auto_now_add': '(True)', 'verbose_name': '"""Дата публикации"""'}), False, 'from django.db import models\n'), (142, 'django.db.models.ForeignKey', 'models.ForeignKey', (['Review'], {'on_delete': 'models.CASCADE', 'related_name': '"""comments"""', 'verbose_name': '"""Отзыв"""'}), False, 'from django.db import models\n'), (148, 'django.db.models.TextField', 'models.TextField', ([], {'verbose_name': '"""Текст"""'}), False, 'from django.db import models\n'), (149, 'django.db.models.ForeignKey', 'models.ForeignKey', (['CustomUser'], {'on_delete': 'models.CASCADE', 'related_name': '"""comments"""', 'verbose_name': '"""Автор"""'}), False, 'from django.db import models\n'), (155, 'django.db.models.DateTimeField', 'models.DateTimeField', ([], {'auto_now_add': '(True)', 'verbose_name': '"""Дата публикации"""'}), False, 'from django.db import models\n'), (15, 'django.core.exceptions.ValidationError', 'ValidationError', (['"""Год выпуска превышает текущий!"""'], {}), False, 'from django.core.exceptions import ValidationError\n'), (14, 'datetime.datetime.now', 'dt.datetime.now', ([], {}), True, 'import datetime as dt\n'), (128, 'django.db.models.UniqueConstraint', 'models.UniqueConstraint', ([], {'fields': "['author', 'title']", 'name': '"""unique review"""'}), False, 'from django.db import models\n'), (116, 'django.core.validators.MinValueValidator', 'MinValueValidator', (['(1)'], {}), False, 'from django.core.validators import MinValueValidator, MaxValueValidator\n'), (117, 'django.core.validators.MaxValueValidator', 'MaxValueValidator', (['(10)'], {}), False, 'from django.core.validators import MinValueValidator, MaxValueValidator\n')]