"""
TODO: I think this has to be moved from here
"""
from yta_math_easings.enums import EasingFunctionName
from dataclasses import dataclass
from typing import Union


@dataclass
class TransitionSpecification:
    """
    The specification of a transition we will implement,
    including the type, the parameters and everything we
    need to correctly implement it.

    To check the `node_names` that are available, please
    go to the next path:
    - `tracks/items/transition/transition_node_registry.py`
    """

    def __init__(
        self,
        node_name: str,
        parameters: dict,
        easing_function: Union[EasingFunctionName, str] = 'linear'
    ):
        self.node_name: str = node_name
        """
        The name of the node we will use for the transition.
        """
        self.parameters: dict = parameters
        """
        All the parameters we need to correctly instantiate
        the transition node.
        """
        self.easing_function: EasingFunctionName = EasingFunctionName.to_enum(easing_function)
        """
        The easing function we want to apply for the
        progress of the transition, which is `linear`
        by default.
        """

    @staticmethod
    def default(
    ):
        """
        Get the `TransitionSpecification` by default, ready
        to be used in the system.
        """
        from yta_editor.tracks.items.transition.transition_node_registry import TransitionNodeRegistry

        # TODO: Review this, maybe not the best way to have a default
        return TransitionSpecification(
            node_name = TransitionNodeRegistry.get_default_key(),
            parameters = {
                'border_smoothness': 0.02
            },
            easing_function = 'linear'
        )

"""
Considering that 'CircleOpeningTransitionProcessor',
which is a valid and working transition node processor,
has the 'border_smoothness' parameter, we should have
it in the `parameters` field, and the `node_name` should
be `CircleOpeningTransitionProcessor` or similar.

TODO: In a near future we should implement a system
to dynamically validate the parameters we provide to 
the nodes, including type, minimum and maximum value,
etc. Check this code below as inspiration:

--------
@dataclass(frozen=True)
class ParameterSpec:
    name: str
    type: type
    required: bool = True
    default: Any = None
    min: float | None = None
    max: float | None = None

# This is one example of parameters definition
class CircleOpeningTransitionProcessor:
    PARAMS = [
        ParameterSpec("center", tuple),
        ParameterSpec("border_smoothness", float, default=0.0, min=0.0, max=1.0),
        ParameterSpec("invert", bool, default=False),
    ]

# This would be the static validator helper
class TransitionParamValidator:
    @staticmethod
    def validate(specs, params):
        for spec in specs:
            if spec.name not in params:
                if spec.required and spec.default is None:
                    raise ValueError(f"Missing param: {spec.name}")
                params[spec.name] = spec.default

            value = params[spec.name]

            if not isinstance(value, spec.type):
                raise TypeError(f"{spec.name} must be {spec.type}")

            if spec.min is not None and value < spec.min:
                raise ValueError(f"{spec.name} < {spec.min}")

            if spec.max is not None and value > spec.max:
                raise ValueError(f"{spec.name} > {spec.max}")

# We would validate like this:
processor_cls = TransitionProcessorRegistry.get(spec.processor)

TransitionParamValidator.validate(
    processor_cls.PARAMS,
    spec.params
)

# And we could even have animated values that
# depend on the context of the specific frame
# so would be evaluated per frame.
class AnimatedFloat:
    def evaluate(self, ctx) -> float: ...
"""