import os
import time
import requests


def get_video(link_audio: str,  image_url: str, path_video: str,) -> None:
    """
    Creates a video with d-id and saves it.
    :param link_audio: url of the audio in the bucket used for the video
    :param path_video: path for saving the video file
    :param image_url: url with the base image used for the video
    :return: None
    :raises Exception: if there was a problem with D-ID
    """
    try:
        id_video = _create_talk(link_audio, image_url)
    except Exception as e:
        raise e

    link_video = _get_url_talk(id_video)

    # Saves the video into a file to later upload it to the cloud
    name = f'{path_video}.mp4'
    try:
        with requests.get(link_video) as r:
            r.raise_for_status()  # Raises an exception for HTTP errors
            if r.status_code == 200:
                with open(name, 'wb') as outfile:
                    outfile.write(r.content)
    except requests.exceptions.RequestException as e:
        raise Exception(f"Network-related error while downloading the video: {e}")
    except ValueError as e:
        raise Exception(e)
    except Exception as e:
        raise Exception(f"An unexpected error occurred: {e}")


def _create_talk(link_audio: str, image_url: str) -> str:
    """
    Creates and returns the id of the talk made with d-id.
    :param link_audio: url of the audio in the bucket used for the video
    :param image_url: url with the base image used for the video
    :return: id of the talk
    :raises Exception: if there was a problem while generating the talk
    """
    url = "https://api.d-id.com/talks"

    payload = {
        "script": {
            "type": "audio",
            "provider": {
                "type": "microsoft",
                "voice_id": "en-US-JennyNeural"
            },
            "ssml": "false",
            "audio_url": link_audio
        },
        "config": {
            "fluent": "false",
            "pad_audio": "0.0",
            "stitch": True
        },
        "source_url": image_url
    }
    headers = {
        "accept": "application/json",
        "content-type": "application/json",
        "authorization": f"Basic {os.getenv('D_ID_KEY')}"
    }

    response = requests.post(url, json=payload, headers=headers)
    r = response.json()

    try:
        talk_id = r['id']
        return talk_id

    # Probably there are no more available credits
    except KeyError:
        raise Exception(f"D-ID response is missing 'id' key. Returned error: {r}")


def _get_url_talk(id_video: str) -> str:
    """
    Gets the url of the finished talk
    :param id_video: id of the previously created talk
    :return: url of the video
    """
    url = f"https://api.d-id.com/talks/{id_video}"

    while True:
        headers = {
            "accept": "application/json",
            "authorization": f"Basic {os.getenv('D_ID_KEY')}"
        }
        response = requests.get(url, headers=headers)
        r = response.json()

        if r['status'] == 'done':
            break
        time.sleep(1)  # Sleep until the video is ready

    return r['result_url']