package me.koba1.led.animations;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Getter;
import lombok.Setter;
import me.koba1.led.animations.idle.RainbowAnimation;
import me.koba1.led.animations.idle.SolidAnimation;
import me.koba1.led.animations.idle.WaveAnimation;
import me.koba1.led.audio.AudioProcessor;
import me.koba1.led.model.LedStrip;
import me.koba1.led.model.colors.KobaOutputColor;
import me.koba1.led.utils.AnimationResolver;
import org.reflections.Reflections;
import tools.jackson.databind.annotation.JsonTypeIdResolver;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.CUSTOM,
        include = JsonTypeInfo.As.PROPERTY,
        property = "animationTypeId",
        visible = true
)
@JsonTypeIdResolver(AnimationResolver.class)
@JsonPropertyOrder({ "id", "animationTypeId" })
@Setter
@Getter
public abstract class BaseAnimation {
    protected int id;

    @JsonIgnore protected KobaOutputColor previousColors;
    @JsonIgnore protected KobaOutputColor outputColors;

    public BaseAnimation(int id) {
        this.previousColors = new KobaOutputColor();
        this.outputColors = new KobaOutputColor();
        this.id = id;
    }

    public KobaOutputColor getColors(LedStrip ledStrip) { // ÁT KELL ADNI A LEDSTRIPET THREAD-SAFE MIATT
        return null;
    }
    public KobaOutputColor getColors(LedStrip ledStrip, AudioProcessor.AudioState s) { // ÁT KELL ADNI A LEDSTRIPET THREAD-SAFE MIATT
        return null;
    }

    // public abstract KobaOutputColor getColors(List<Object> audio);

    private static final List<Supplier<BaseAnimation>> REGISTRY = new ArrayList<>();

    protected static void register(Supplier<BaseAnimation> supplier) {
        REGISTRY.add(supplier);
    }

    public static List<BaseAnimation> getDefaultAnimations() {
        return REGISTRY.stream()
                .map(Supplier::get)
                .toList();
    }
}
