from yta_editor.transformations.time_function import TimeFunction, LinearTimeFunction
from abc import ABC, abstractmethod
from dataclasses import dataclass


class Effect(ABC):
    """
    *Abstract class*

    Class to represent an effect that we will apply in
    a specific time moment, considering the params
    defined for it.

    An effect is something that uses a frame as an input
    and returns another input based on the changes, such
    as: blur, color correction, mask, chroma, etc.
    """

    @abstractmethod
    def _eval_params(
        self,
        t: float
    ):
        """
        *For internal use only*

        Evaluate the parameters and obtain the values to apply
        for the specific `t` time moment provided.
        """
        pass

    @abstractmethod
    def apply(
        self,
        frame,
        t: float
    ):
        """
        Apply the effect to the given `frame` for the specific
        `t` time moment.
        """
        pass

class EffectParams(ABC):
    """
    *Abstract class*

    Class to represent the parameters to use when
    applying an effect.
    """

    pass
    
# TODO: We need to define all the specific effect
# params to be able to build them properly missing
# no fields
@dataclass
class BrightnessEffectParams(EffectParams):
    """
    The parameters to use when applying the effect
    that changes the brightness for a specific `t`
    time moment.

    This will be returned by the effect when
    calculated, for a specific `t` time moment.
    """

    def __init__(
        self,
        value: float
    ):
        self.value: float = value
        """
        The value to apply as brightness.
        """
        

class BrightnessEffect(Effect):
    """
    The effect that will change the brightness of the
    element according to the provided conditions.
    """

    def __init__(
        self,
        value: TimeFunction = LinearTimeFunction(0, 1, 0, 100)
    ):
        self.value: TimeFunction = value
        """
        The `TimeFunction` that defines the value that should
        be applied for the specific `t` time moment requested.
        """

    def _eval_params(
        self,
        t: float
    ) -> BrightnessEffectParams:
        return BrightnessEffectParams(self.value.value_at(t))

    def apply(
        self,
        # TODO: Set the type
        frame,
        t: float,
    ):
        
        params = self._eval_params(t)

        if params.value == 0:
            return frame
        
        # TODO: Apply the brightness change and return modified
        return frame