from youtube_autonomous.elements.builder.element_builder import ElementBuilder
from youtube_autonomous.elements.validator.element_parameter_validator import ElementParameterValidator
from youtube_autonomous.elements.builder.enums import TextPremade
from yta_general_utils.programming.parameter_obtainer import ParameterObtainer
from yta_general_utils.programming.parameter_validator import PythonValidator
from moviepy import VideoFileClip


class TextElementBuilder(ElementBuilder):

    @classmethod
    def text_premade_name_to_class(
        cls,
        text_premade_name: str
    ):
        """
        Returns the corresponding text premade class according to
        the provided 'text_premade_name'. If no text premade class
        found, the return will be None.
        """
        valid_name = TextPremade.get_valid_name(text_premade_name)

        if not valid_name:
            raise Exception(f'The provided text premade name "{text_premade_name}" is not valid. The valid ones are: {TextPremade.get_all_names_as_str()}')
        
        return TextPremade[valid_name].value
    
    @classmethod
    def _build(
        cls,
        element: dict
    ) -> VideoFileClip:
        """
        For internal use only.
        """
        text_premade_name = element.keywords
        text_premade_class = cls.text_premade_name_to_class(text_premade_name)
        method = text_premade_class.generate

        parameters = cls.get_parameters_from_method(
            method = method,
            element = element,
            parameters_to_ignore = ['output_filename'],
            parameters_strictly_from_element = ['duration', 'text']
            # TODO: Maybe force 'duration' and 'text' to
            # be obtained from segment
        )

        return cls.build_custom_from_text_premade_name(text_premade_name, **parameters)

    @classmethod
    def build_from_enhancement(
        cls,
        enhancement: dict
    ):
        return cls._build(enhancement)

    @classmethod
    def build_from_segment(
        cls,
        segment: dict
    ):
        return cls._build(segment)
    
    @classmethod
    def build_custom_from_text_premade_name(
        cls,
        text_premade_name,
        **parameters
    ):
        """
        This method instantiates the 'text_animation_class' Manim
        text animation class and uses the provided 'parameters' to
        build the text animation. The provided 'parameters' must 
        fit the ones requested by the provided class 'generate'
        method.
        """
        ElementParameterValidator.validate_premade_name(text_premade_name)

        text_premade_class = cls.text_premade_name_to_class(text_premade_name)

        # We generate the animation to return it
        filename = text_premade_class().generate(**parameters)

        # TODO: Maybe 'mask' to set background as transparent if available (?)
        return VideoFileClip(filename)