import subprocess, json, requests, logging

from django.contrib.contenttypes.models import ContentType

from moviepy.editor import VideoFileClip

from .models import Video, Playlist, TagToObject, DYNAMIC, PlaylistVideo


log = logging.getLogger('send_video_to_s3')


def download_file(url):
    log.info(f'Downloading file {url}...')
    local_filename = url.split('/')[-1]
    # NOTE the stream=True parameter below
    with requests.get(url, stream=True) as r:
        r.raise_for_status()
        with open(local_filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=8192):
                f.write(chunk)

    log.info('get content successfully!')
    file = open(local_filename, 'rb')

    return file


def handle_uploaded_file(f, file_name):
    with open(file_name, 'wb+') as destination:
        for chunk in f.chunks(chunk_size=4097152):
            destination.write(chunk)


def generate_thumbnail(video_path, video_name):
    clip = VideoFileClip(video_path)
    log.info('get clip successfully!')
    thumbnail_name = video_name.split('.')[0]
    thumbnail_name = f'{thumbnail_name}.jpg'
    log.info(f'thumbnail name: {thumbnail_name}')
    clip.save_frame(thumbnail_name, t=1.00)
    log.info('create frame successfully!')

    thumbnail = open(thumbnail_name, 'rb')
    log.info('open thumbnail successfully!')

    thumbnail_name = thumbnail_name.split('/')[-1]

    return thumbnail, thumbnail_name


def get_video_duration(filename):
    result = subprocess.check_output(
        f'ffprobe -v quiet -show_streams -select_streams v:0 -of json "{filename}"',
        shell=True
    ).decode()

    duration = json.loads(result)['streams'][0]['duration']

    try:
        duration = int(duration)
    except ValueError:
        duration = float(duration)

    return duration


def add_video_to_playlist(video):
    video_content_type = ContentType.objects.get_for_model(Video)
    playlist_content_type = ContentType.objects.get_for_model(Playlist)

    tag_ids = list(TagToObject.objects.filter(
        content_type=video_content_type,
        object_id=video.id,
    ).values_list('tag_id', flat=True))

    if tag_ids:
        playlist_ids = list(TagToObject.objects.filter(
            content_type=playlist_content_type,
            tag_id__in=tag_ids,
        ).values_list('object_id', flat=True))

        if playlist_ids:
            playlists = Playlist.objects.filter(id__in=playlist_ids, type=DYNAMIC)

            for playlist in playlists:
                PlaylistVideo.objects.update_or_create(
                    playlist=playlist,
                    video=video,
                )


def add_video_to_new_playlist(playlist):
    video_content_type = ContentType.objects.get_for_model(Video)
    playlist_content_type = ContentType.objects.get_for_model(Playlist)

    tag_ids = list(TagToObject.objects.filter(
        content_type=playlist_content_type,
        object_id=playlist.id,
    ).values_list('tag_id', flat=True))

    if tag_ids:
        video_ids = list(TagToObject.objects.filter(
            content_type=video_content_type,
            tag_id__in=tag_ids,
        ).values_list('object_id', flat=True))

        if video_ids:
            for video in Video.objects.filter(id__in=video_ids):
                PlaylistVideo.objects.update_or_create(
                    playlist=playlist,
                    video=video,
                )