package me.koba1.led.animations.audio.bass;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import me.koba1.led.animations.ColoredAnimation;
import me.koba1.led.animations.audio.Audio;
import me.koba1.led.audio.AudioProcessor;
import me.koba1.led.audio.BandType;
import me.koba1.led.model.LedStrip;
import me.koba1.led.model.colors.AnimationColor;
import me.koba1.led.model.colors.AnimationColorType;
import me.koba1.led.model.colors.KobaColor;
import me.koba1.led.model.colors.KobaOutputColor;
import me.koba1.led.utils.ColorUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Getter
public class BassAnimation extends ColoredAnimation implements Audio {

    private float threshold;
    private long fadeOutTime;

    @JsonIgnore
    private long fadeOutState;

    public BassAnimation(float threshold, long fadeOutTime, Map<AnimationColorType, AnimationColor> colors) {
        super(100, colors);
        this.threshold = threshold;
        this.fadeOutTime = fadeOutTime;
        this.fadeOutState = 0;
    }

    @Override
    public KobaOutputColor getColors(LedStrip ledStrip) {
        return null;
    }

    @Override
    public KobaOutputColor getColors(LedStrip ledStrip, AudioProcessor.AudioState s) {
        long unixTime = System.currentTimeMillis();
        outputColors.clear();
        AnimationColor bg = this.colors.get(AnimationColorType.BACKGROUND);
        AnimationColor fg = this.colors.get(AnimationColorType.FOREGROUND);
        //outputColors.fill(bg.getColor(ledStrip.getLedCount()));

        float bass = s.bands.get(BandType.BASS) > s.bands.get(BandType.SUB_BASS) ? s.bands.get(BandType.BASS) : s.bands.get(BandType.SUB_BASS);

        List<KobaColor> colors = fg.getColor(ledStrip.getLedCount());

        if(bass >= threshold) {
            fadeOutState = unixTime + fadeOutTime;
        }

        if(this.fadeOutState >= unixTime) {
            long millisDiff = this.fadeOutState - unixTime;

            List<KobaColor> newColors = new ArrayList<>();
            for (KobaColor color : colors) {
                int alpha = (int) ((float) millisDiff / this.fadeOutTime * color.getAlpha());
                newColors.add(color.withAlpha(alpha));
            }

            //System.out.println("Filled output colors: " + newColors);
            outputColors.fill(newColors);
        }


        KobaOutputColor difference = ColorUtils.getDifference(this.previousColors, outputColors);
        this.previousColors.set(this.outputColors);
        return difference;
    }

    static {
        register(() -> new BassAnimation(
                0.9f,
                500,
                Map.of(AnimationColorType.FOREGROUND, new AnimationColor(),
                        AnimationColorType.BACKGROUND, new AnimationColor().type(AnimationColor.ColorType.GRADIENT))));
    }
}
