from uuid import uuid4
from django.db import models
from django.conf import settings
from django.db.models.aggregates import Sum

class PersonManager(models.Manager):
    def all_with_prefetch_movies(self):
        qs = self.get_queryset()
        return qs.prefetch_related(
                'directed',
                'writing_credits',
                )

class Person(models.Model):
    first_name = models.CharField(max_length=140)
    last_name = models.CharField(max_length=140)
    born = models.DateField()

    objects = PersonManager()

    class Meta:
        ordering = ('last_name', 'first_name')

    def __str__(self):
        return '{}, {} ({})'.format(
                    self.last_name,
                    self.first_name, 
                    self.born)

class MovieManager(models.Manager):
    def all_with_related_persons(self):
        qs = self.get_queryset()
        qs = qs.select_related(
                'director')
        qs = qs.prefetch_related(
                'writers')
        return qs

    def all_with_related_persons_and_score(self):
        qs = self.all_with_related_persons()
        qs = qs.annotate(score=Sum('vote__value'))
        return qs


class myMovie(models.Model):
    title = models.CharField(max_length=140)
    plot = models.TextField()
    year = models.PositiveIntegerField()
    director = models.ForeignKey(
            to='Person',
            null=True,
            on_delete=models.SET_NULL,
            related_name='directed',
            blank=True)
    writers = models.ManyToManyField(
            to='Person',
            related_name='writing_credits',
            blank=True)

    objects = MovieManager()

    def __str__(self):
        return '{} ({})'.format(
        self.title, self.year)

class VoteManager(models.Manager):
    def get_vote_or_unsaved_blank_vote(self, movie, user):
        try:
            return Vote.objects.get(
                    movie=movie,
                    user=user)
        except Vote.DoesNotExist:
            return Vote(
                    movie=movie,
                    user=user)

class Vote(models.Model):
    UP = 1
    DOWN = -1
    VALUE_CHOICES = (
            (UP, "LIKE",),
            (DOWN, "DISLIKE",),
            )

    value = models.SmallIntegerField(
            choices=VALUE_CHOICES,
            )
    user = models.ForeignKey(
            settings.AUTH_USER_MODEL,
            on_delete=models.CASCADE
            )
    movie = models.ForeignKey(
            myMovie,
            on_delete=models.CASCADE,
            )
    voted_on = models.DateTimeField(
            auto_now=True
            )

    objects = VoteManager()

    class Meta:
        unique_together = ('user', 'movie')

def movie_directory_path_with_uuid(
        instance, 
        filename):
    return '{}/{}.{}'.format(
            instance.movie_id,
            uuid4(),
            filename.split('.')[-1]
            )

class MovieImage(models.Model):
    image = models.ImageField(upload_to=movie_directory_path_with_uuid)
    uploaded = models.DateTimeField(auto_now_add=True)
    movie = models.ForeignKey('myMovie', on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)


from uuid import uuid4
from django.db import models
from django.conf import settings
from django.db.models.aggregates import Sum

class PersonManager(models.Manager):
    def all_with_prefetch_movies(self):
        qs = self.get_queryset()
        return qs.prefetch_related(
                'directed',
                'writing_credits',
                )

class Person(models.Model):
    first_name = models.CharField(max_length=140)
    last_name = models.CharField(max_length=140)
    born = models.DateField()

    objects = PersonManager()

    class Meta:
        ordering = ('last_name', 'first_name')

    def __str__(self):
        return '{}, {} ({})'.format(
                    self.last_name,
                    self.first_name, 
                    self.born)

class MovieManager(models.Manager):
    def all_with_related_persons(self):
        qs = self.get_queryset()
        qs = qs.select_related(
                'director')
        qs = qs.prefetch_related(
                'writers')
        return qs

    def all_with_related_persons_and_score(self):
        qs = self.all_with_related_persons()
        qs = qs.annotate(score=Sum('vote__value'))
        return qs


class myMovie(models.Model):
    title = models.CharField(max_length=140)
    plot = models.TextField()
    year = models.PositiveIntegerField()
    director = models.ForeignKey(
            to='Person',
            null=True,
            on_delete=models.SET_NULL,
            related_name='directed',
            blank=True)
    writers = models.ManyToManyField(
            to='Person',
            related_name='writing_credits',
            blank=True)

    objects = MovieManager()

    def __str__(self):
        return '{} ({})'.format(
        self.title, self.year)

class VoteManager(models.Manager):
    def get_vote_or_unsaved_blank_vote(self, movie, user):
        try:
            return Vote.objects.get(
                    movie=movie,
                    user=user)
        except Vote.DoesNotExist:
            return Vote(
                    movie=movie,
                    user=user)

class Vote(models.Model):
    UP = 1
    DOWN = -1
    VALUE_CHOICES = (
            (UP, "LIKE",),
            (DOWN, "DISLIKE",),
            )

    value = models.SmallIntegerField(
            choices=VALUE_CHOICES,
            )
    user = models.ForeignKey(
            settings.AUTH_USER_MODEL,
            on_delete=models.CASCADE
            )
    movie = models.ForeignKey(
            myMovie,
            on_delete=models.CASCADE,
            )
    voted_on = models.DateTimeField(
            auto_now=True
            )

    objects = VoteManager()

    class Meta:
        unique_together = ('user', 'movie')

def movie_directory_path_with_uuid(
        instance, 
        filename):
    return '{}/{}.{}'.format(
            instance.movie_id,
            uuid4(),
            filename.split('.')[-1]
            )

class MovieImage(models.Model):
    image = models.ImageField(upload_to=movie_directory_path_with_uuid)
    uploaded = models.DateTimeField(auto_now_add=True)
    movie = models.ForeignKey('myMovie', on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)

