from __future__ import annotations

import os
from math import log

import mutagen
from django.core.files import storage
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from mutagen import File
from mutagen.wave import WAVE
from pydub import AudioSegment
from rest_framework.exceptions import NotFound

from apps.artiste.models import AudioMedia


class GetObjectMixin(object):
    @staticmethod
    def get_object_by_model(model, id):
        try:
            obj = model.objects.get(id=id)
        except model.DoesNotExist as e:
            raise NotFound(f'Object not found with params {id} on model {model.__name__}') from e

        return obj

    def get_related_object_by_model(self, model, id, related_field):
        try:
            obj = model.objects.select_related(related_field).get(id=id)
        except model.DoesNotExist as e:
            raise NotFound(f'Object not found with params {id} on model {model.__name__}') from e

        return getattr(obj, related_field)


def calculate_audio_media_score(audio_media: AudioMedia):
    likes_count = audio_media.get_likes_count()
    dislikes_count = audio_media.get_dislikes_count()

    if likes_count == 0:
        return 0

    score = (likes_count + 1) / (dislikes_count + 1) * log(likes_count + 1)

    # Save the score to the AudioMedia model
    audio_media.score = score
    audio_media.save()

    return score


def audio_duration(length):
    hours = length // 3600  # calculate in hours
    length %= 3600
    mins = length // 60  # calculate in minutes
    length %= 60
    seconds = length  # calculate in seconds

    return int(hours), int(mins), seconds


def trim_audio(trim_start, trim_end, audio_file, new_name=None):
    # Load the audio file using pydub
    audio = AudioSegment.from_file(audio_file)

    trim_start_millisec = trim_start * 1000
    trim_end_millisec = trim_end * 1000

    # audio = File(audio_file)
    # audio_info = audio.info
    # length = audio_info.length
    # hours, mins, seconds = audio_duration(length)
    # print(f'Total Duration: {hours}:{mins}:{seconds}')

    # Trim the audio
    trimmed_audio = audio[trim_start_millisec:trim_end_millisec]

    # Create a new name for the trimmed audio file
    if new_name is None:
        # new_name = f'{os.path.splitext(audio_file)[0]}_trimmed{os.path.splitext(audio_file)[1]}'
        new_name = f'_trimmed{os.path.splitext(audio_file)[1]}'

    # Save the trimmed audio to a new file using default_storage
    new_file = default_storage.save(
        new_name, ContentFile(trimmed_audio.export(format=os.path.splitext(audio_file)[1][1:]), 'rb')
    )

    # Export the trimmed audio to a new file with the new name
    # new_file = trimmed_audio.export(new_name, format=os.path.splitext(audio_file)[1][1:])

    # Return the trimmed audio as an AudioSegment object
    return new_name, default_storage.path(new_file)
