package me.koba1.led.utils;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import me.koba1.led.animations.BaseAnimation;
import me.koba1.led.animations.audio.bass.BassAnimation;
import me.koba1.led.animations.audio.bass.BassTrebleAnimation;
import me.koba1.led.animations.audio.bass.OuterWaveBassAnimation;
import me.koba1.led.animations.audio.bass.RangeFlashAnimation;
import me.koba1.led.animations.idle.RainbowAnimation;
import me.koba1.led.animations.idle.SolidAnimation;
import me.koba1.led.animations.idle.WaveAnimation;
import tools.jackson.core.JacksonException;
import tools.jackson.databind.DatabindContext;
import tools.jackson.databind.JavaType;
import tools.jackson.databind.jsontype.impl.TypeIdResolverBase;

import java.util.Map;

public class AnimationResolver extends TypeIdResolverBase {
    private static final Map<Integer, Class<? extends BaseAnimation>> TYPES = Map.of(
            0, SolidAnimation.class,
            1, WaveAnimation.class,
            2, RainbowAnimation.class,

            100, BassAnimation.class,
            101, OuterWaveBassAnimation.class,
            102, RangeFlashAnimation.class,
            103, BassTrebleAnimation.class
    );

    public AnimationResolver() {
        super();
    }

    @Override
    public String idFromValue(DatabindContext ctxt, Object value) throws JacksonException {
        return String.valueOf(((BaseAnimation) value).getId());
    }

    @Override
    public String idFromValueAndType(DatabindContext ctxt, Object value, Class<?> suggestedType) throws JacksonException {
        return idFromValue(ctxt, value);
    }

    @Override
    public JavaType typeFromId(DatabindContext context, String id) {
        try {
            int typeId = Integer.parseInt(id.trim());
            Class<? extends BaseAnimation> clazz = TYPES.get(typeId);

            if (clazz == null) {
                throw new IllegalArgumentException("Unknown animation id: " + typeId);
            }

            return context.constructType(clazz);
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid animation id format: '" + id + "'", e);
        }
    }

    @Override
    public JsonTypeInfo.Id getMechanism() {
        return null;
    }

    public static Class<? extends BaseAnimation> getAnimationById(int id) {
        return TYPES.get(id);
    }
}
