from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation

from pytils.translit import slugify

from storages.backends.s3boto3 import S3Boto3Storage

from cp_video.utils import asset_upload


READY = 'ready'
PROGRESS = 'progress'
FAIL = 'fail'
STATUS_CHOICES = (
    (READY, 'Ready'),
    (PROGRESS, 'Progress'),
    (FAIL, 'Fail'),
)

DYNAMIC = 'dynamic'
FREESTYLE = 'freestyle'
TYPE_CHOICES = (
    (DYNAMIC, 'Dynamic'),
    (FREESTYLE, 'Freestyle'),
)

LAST_UPDATED = 'last_updated'
MOST_RECENTLY_PUBLISHED = 'most_recently_published'
TITLE_A_Z = 'title_a_z'
TITLE_Z_A = 'title_z_a'
SHORTER_FIRST = 'shorter_first'
LONGER_FIRST = 'longer_first'
SORT_CHOICES = (
    (LAST_UPDATED, 'Last updated'),
    (MOST_RECENTLY_PUBLISHED, 'Most recently published'),
    (TITLE_A_Z, 'Title A-Z'),
    (TITLE_Z_A, 'Title Z-A'),
    (SHORTER_FIRST, 'Shorter first'),
    (LONGER_FIRST, 'Longer first'),
)


class BaseModel(models.Model):
    updated = models.DateTimeField(_('updated'), auto_now=True, db_index=True)
    created = models.DateTimeField(_('created'), auto_now_add=True, db_index=True)

    class Meta:
        abstract = True


class Tag(models.Model):
    name = models.CharField(_('name'), max_length=255, db_index=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'Tag'
        verbose_name_plural = 'Tags'

    def __str__(self):
        return self.name


class TagToObject(models.Model):
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE, related_name='tag')
    content_type = models.ForeignKey(
        ContentType,
        on_delete=models.CASCADE,
        related_name='content_type_tag',
        verbose_name=_('content type'),
    )
    object_id = models.PositiveIntegerField(_('object_id'), blank=True, null=True)
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        verbose_name = 'Tag to object'
        verbose_name_plural = 'Tags to objects'

    def __str__(self):
        return str(self.id)


class Category(models.Model):
    name = models.CharField('name', max_length=255, db_index=True)

    class Meta:
        ordering = ('name',)
        verbose_name = 'Category'
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.name


class Video(BaseModel):
    title = models.CharField(_('title'), max_length=255)
    slug = models.SlugField(_('slug'), max_length=255, unique=True, blank=True)
    description = models.TextField(_('description'), blank=True, null=True)
    local_file = models.FileField(
        _('local file'),
        upload_to=asset_upload,
        blank=True,
        null=True,
    )
    s3_file = models.FileField(
        _('AWS S3 file'),
        storage=S3Boto3Storage(bucket_name='clutchpoints-videos'),
        blank=True,
        null=True,
        max_length=500,
    )
    s3_file_upload = models.FileField(
        _('AWS S3 file upload'),
        storage=S3Boto3Storage(bucket_name='clutchpoints-videos'),
        blank=True,
        null=True,
        max_length=500,
    )
    thumbnail = models.ImageField(
        _('thumbnail'),
        upload_to=asset_upload,
        storage=S3Boto3Storage(bucket_name='clutchpoints-videos'),
        blank=True,
        null=True,
        max_length=500,
    )
    creator = models.ForeignKey(
        User,
        verbose_name=_('creator'),
        related_name='creator_video',
        on_delete=models.CASCADE,
        blank=True
    )
    status = models.CharField(
        _('status'),
        choices=STATUS_CHOICES,
        default=PROGRESS,
        max_length=255,
    )
    duration = models.IntegerField(_('duration'), blank=True, null=True)
    closed_captions = models.CharField(
        _('closed_captions'),
        max_length=255,
        blank=True,
        null=True,
    )
    categories = models.ManyToManyField(
        Category,
        verbose_name='categories',
        related_name='video',
        blank=True,
    )
    tags = GenericRelation(TagToObject)

    class Meta:
        ordering = ('title',)
        verbose_name = 'Video'
        verbose_name_plural = 'Videos'

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)

        super().save(*args, **kwargs)


class Playlist(BaseModel):
    title = models.CharField(_('title'), max_length=255)
    description = models.TextField(_('description'), blank=True, null=True)
    sort = models.CharField(choices=SORT_CHOICES, max_length=255, blank=True)
    type = models.CharField(choices=TYPE_CHOICES, max_length=255, blank=True)
    mrss = models.CharField(_('mrss'), max_length=255, blank=True, null=True)
    json = models.CharField(_('json'), max_length=255, blank=True, null=True)
    tags = GenericRelation(TagToObject)

    class Meta:
        ordering = ('title',)
        verbose_name = 'Playlist'
        verbose_name_plural = 'Playlists'

    def __str__(self):
        return self.title


class PlaylistVideo(BaseModel):
    playlist = models.ForeignKey(
        Playlist,
        on_delete=models.CASCADE,
        related_name='playlist_video',
        verbose_name='playlist video',
    )
    video = models.ForeignKey(
        Video,
        on_delete=models.CASCADE,
        related_name='video_playlist',
        verbose_name='video playlist',
    )

    class Meta:
        verbose_name = 'Playlist video'
        verbose_name_plural = 'Playlists video'

    def __str__(self):
        return str(self.id)