import copy

import requests

CREATOMATE_API_KEY = "df9e4382d7e84fe790bf8a2168152be195d5a3568524ceb66ed989a2dea809f7d3065d6803b2e3dd9d02b5e5ec1c9823"
# ACCOUNT_URL = "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/"
# Creatomate 템플릿 정보 전부 가져오기


class Creatomate:
    base_url: str = "https://api.creatomate.com"

    def __init__(self, api_key):
        self.api_key = api_key

    def get_all_templates_data(self) -> dict:
        url = Creatomate.base_url + "/v1/templates"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}",
        }
        response = requests.get(url, headers=headers)
        return response.json()

    # Creatomate 템플릿 ID 로부터 해당 템플릿 정보 가져오기
    def get_one_template_data(self, template_id: str) -> dict:
        url = Creatomate.base_url + f"/v1/templates/{template_id}"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}",
        }
        response = requests.get(url, headers=headers)
        return response.json()

    # 템플릿 정보 파싱하여 리소스 이름 추출하기
    def parse_template_component_name(self, template_source: dict) -> dict:
        def recursive_parse_component(element: dict) -> dict:
            if "name" in element:
                result_element_name_type = {element["name"]: element["type"]}
            else:
                result_element_name_type = {}

            if element["type"] == "composition":
                minor_component_list = [
                    recursive_parse_component(minor) for minor in element["elements"]
                ]
                for minor_component in minor_component_list:  ## WARNING : Same name component should shroud other component. be aware
                    result_element_name_type.update(minor_component)

            return result_element_name_type

        result = {}
        for result_element_dict in [
            recursive_parse_component(component) for component in template_source
        ]:
            result.update(result_element_dict)

        return result

    # 템플릿 정보 이미지/가사/음악 리소스와 매핑하기
    # 이미지는 순차적으로 집어넣기
    # 가사는 개행마다 한 텍스트 삽입
    # Template에 audio-music 항목이 있어야 함. (추가된 템플릿 Cafe뿐임)
    def template_connect_resource_blackbox(
        self, template_id: str, image_url_list: list[str], lyric: str, music_url: str
    ) -> dict:
        template_data = self.get_one_template_data(template_id)
        template_component_data = self.parse_template_component_name(
            template_data["source"]["elements"]
        )

        lyric.replace("\r", "")
        lyric_splited = lyric.split("\n")
        modifications = {}
        for idx, (template_component_name, template_type) in enumerate(
            template_component_data.items()
        ):
            match template_type:
                case "image":
                    modifications[template_component_name] = image_url_list[
                        idx % len(image_url_list)
                    ]
                case "text":
                    modifications[template_component_name] = lyric_splited[
                        idx % len(lyric_splited)
                    ]

        modifications["audio-music"] = music_url

        return modifications

    def elements_connect_resource_blackbox(
        self, elements: list, image_url_list: list[str], lyric: str, music_url: str
    ) -> dict:
        template_component_data = self.parse_template_component_name(elements)

        lyric.replace("\r", "")
        lyric_splited = lyric.split("\n")
        modifications = {}
        for idx, (template_component_name, template_type) in enumerate(
            template_component_data.items()
        ):
            match template_type:
                case "image":
                    modifications[template_component_name] = image_url_list[
                        idx % len(image_url_list)
                    ]
                case "text":
                    modifications[template_component_name] = lyric_splited[
                        idx % len(lyric_splited)
                    ]

        modifications["audio-music"] = music_url

        return modifications

    def modify_element(self, elements: list, modification: dict):
        def recursive_modify(element: dict) -> dict:
            if "name" in element:
                match element["type"]:
                    case "image":
                        element["source"] = modification[element["name"]]
                    case "audio":
                        element["source"] = modification.get(element["name"], "")
                    case "video":
                        element["source"] = modification[element["name"]]
                    case "text":
                        element["source"] = modification.get(element["name"], "")
                    case "composition":
                        for minor in element["elements"]:
                            recursive_modify(minor)

        for minor in elements:
            recursive_modify(minor)

        return elements

    # Creatomate에 생성 요청
    # response에 요청 정보 있으니 풀링 필요
    def make_creatomate_call(self, template_id: str, modifications: dict):
        url = Creatomate.base_url + "/v2/renders"

        data = {"template_id": template_id, "modifications": modifications}
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}",
        }

        response = requests.post(url, json=data, headers=headers)
        return response

    # Creatomate에 생성 요청 without template
    # response에 요청 정보 있으니 풀링 필요
    def make_creatomate_custom_call(self, source: str):
        url = Creatomate.base_url + "/v2/renders"
        data = source
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}",
        }

        response = requests.post(url, json=data, headers=headers)
        return response

    def calc_scene_duration(self, template: dict):
        total_template_duration = 0
        for elem in template["source"]["elements"]:
            try:
                if elem["type"] == "audio":
                    continue
                total_template_duration += elem["duration"]
                if "animations" not in elem:
                    continue
                for animation in elem["animations"]:
                    assert animation["time"] == 0  # 0이 아닌 경우 확인 필요
                    if animation["transition"]:
                        total_template_duration -= animation["duration"]
            except:
                print(elem)
        return total_template_duration

    def extend_template_duration(self, template: dict, target_duration: float):
        template["duration"] = target_duration
        total_template_duration = self.calc_scene_duration(template)
        extend_rate = target_duration / total_template_duration
        new_template = copy.deepcopy(template)
        for elem in new_template["source"]["elements"]:
            try:
                if elem["type"] == "audio":
                    continue
                elem["duration"] = elem["duration"] * extend_rate
                if "animations" not in elem:
                    continue
                for animation in elem["animations"]:
                    assert animation["time"] == 0  # 0이 아닌 경우 확인 필요
                    animation["duration"] = animation["duration"] * extend_rate
            except:
                print(elem)
        return new_template


# Azure사용한 legacy 코드 원본
# def template_connect_resource_blackbox(template_id, user_idx, task_idx):
#     secret_client = get_keyvault_client()
#     account_url = secret_client.get_secret(BLOB_ACCOUNT_URL_KEY).value
#     media_folder_path = f"{user_idx}/{task_idx}"
#     lyric_path = f"{media_folder_path}/lyric.txt"
#     lyric = az_storage.az_storage_read_ado2_media(lyric_path).readall().decode('UTF-8')
#     media_list = az_storage.az_storage_get_ado2_media_list(media_folder_path)
#     image_list = [media.name for media in media_list if '/crawling-images/' in media.name]
#     template_data = get_one_template_data(template_id)
#     template_component_data = parse_template_component_name(template_data['source']['elements'])
#     lyric.replace("\r", "")
#     lyric_splited = lyric.split("\n")
#     modifications = {}
#     for idx, (template_component_name, template_type) in enumerate(template_component_data.items()):
#         match template_type:
#             case 'image':
#                 modifications[template_component_name] = f"{account_url}/{BLOB_CONTAINER_NAME}/{image_list[idx % len(image_list)]}"
#             case 'text':
#                 modifications[template_component_name] = lyric_splited[idx % len(lyric_splited)]

#     modifications["audio-music"] = f"{account_url}/{BLOB_CONTAINER_NAME}/{BLOB_MEDIA_FOLDER}/{media_folder_path}/music_mureka.mp3"
#     print(modifications)

#     return modifications
