package zenith.zov.client.modules.impl.render;

import com.darkmagician6.eventapi.EventTarget;
import net.minecraft.entity.Entity;
import net.minecraft.entity.decoration.EndCrystalEntity;
import net.minecraft.entity.player.PlayerEntity;
import zenith.zov.base.events.impl.render.EventRender3D;
import zenith.zov.client.modules.api.Category;
import zenith.zov.client.modules.api.Module;
import zenith.zov.client.modules.api.ModuleAnnotation;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.ModeSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.utility.interfaces.IMinecraft;

@ModuleAnnotation(
    name = "Shaders",
    category = Category.RENDER,
    description = "Applies shader effects to entities and hands"
)
public final class Shaders extends Module implements IMinecraft {
    public static final Shaders INSTANCE = new Shaders();
    private final BooleanSetting hands = new BooleanSetting("Hands", true);
    private final BooleanSetting players = new BooleanSetting("Players", true);
    private final BooleanSetting self = new BooleanSetting("Self", true);
    private final BooleanSetting friends = new BooleanSetting("Friends", true);
    private final BooleanSetting crystals = new BooleanSetting("Crystals", true);
    private final BooleanSetting creatures = new BooleanSetting("Creatures", false);
    private final BooleanSetting monsters = new BooleanSetting("Monsters", false);
    private final BooleanSetting ambients = new BooleanSetting("Ambients", false);
    private final BooleanSetting others = new BooleanSetting("Others", false);
    private final ModeSetting mode = new ModeSetting("Mode", "Default", "Default", "Gradient", "Smoke", "Outline", "Fill");
    private final ModeSetting handsMode = new ModeSetting("HandsMode", "Default", "Default", "Gradient", "Smoke", "Outline", "Fill");
    private final NumberSetting maxRange = new NumberSetting("MaxRange", 64.0F, 16.0F, 256.0F, 1.0F);
    private final NumberSetting factor = new NumberSetting("GradientFactor", 2.0F, 0.0F, 20.0F, 0.1F);
    private final NumberSetting gradient = new NumberSetting("Gradient", 2.0F, 0.0F, 20.0F, 0.1F);
    private final NumberSetting alpha2 = new NumberSetting("GradientAlpha", 170.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting lineWidth = new NumberSetting("LineWidth", 2.0F, 0.0F, 500.0F, 1.0F);
    private final NumberSetting quality = new NumberSetting("Quality", 3.0F, 0.0F, 6.0F, 1.0F);
    private final NumberSetting octaves = new NumberSetting("SmokeOctaves", 10.0F, 5.0F, 30.0F, 1.0F);
    private final NumberSetting fillAlpha = new NumberSetting("FillAlpha", 170.0F, 0.0F, 255.0F, 1.0F);
    private final BooleanSetting glow = new BooleanSetting("SmokeGlow", true);
    private final NumberSetting outlineColorRed = new NumberSetting("Outline Red", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting outlineColorGreen = new NumberSetting("Outline Green", 255.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting outlineColorBlue = new NumberSetting("Outline Blue", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting outlineColorAlpha = new NumberSetting("Outline Alpha", 136.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeOutlineRed = new NumberSetting("Smoke Outline Red", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeOutlineGreen = new NumberSetting("Smoke Outline Green", 255.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeOutlineBlue = new NumberSetting("Smoke Outline Blue", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeOutline2Red = new NumberSetting("Smoke Outline2 Red", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeOutline2Green = new NumberSetting("Smoke Outline2 Green", 255.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeOutline2Blue = new NumberSetting("Smoke Outline2 Blue", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting fillColorRed = new NumberSetting("Fill Red", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting fillColorGreen = new NumberSetting("Fill Green", 255.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting fillColorBlue = new NumberSetting("Fill Blue", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeFillRed = new NumberSetting("Smoke Fill Red", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeFillGreen = new NumberSetting("Smoke Fill Green", 255.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeFillBlue = new NumberSetting("Smoke Fill Blue", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeFill2Red = new NumberSetting("Smoke Fill2 Red", 0.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeFill2Green = new NumberSetting("Smoke Fill2 Green", 255.0F, 0.0F, 255.0F, 1.0F);
    private final NumberSetting smokeFill2Blue = new NumberSetting("Smoke Fill2 Blue", 0.0F, 0.0F, 255.0F, 1.0F);

    private Shaders() {
    }

    public boolean shouldRender(Entity entity) {
        if (entity == null) {
            return false;
        } else if (mc.player == null) {
            return false;
        } else if (mc.player.squaredDistanceTo(entity.getPos()) > (double)(this.maxRange.getCurrent() * this.maxRange.getCurrent())) {
            return false;
        } else if (entity instanceof PlayerEntity) {
            return entity == mc.player && !this.self.isEnabled() ? false : this.players.isEnabled();
        } else if (entity instanceof EndCrystalEntity) {
            return this.crystals.isEnabled();
        } else {
            return switch (entity.getType().getSpawnGroup()) {
                case CREATURE, WATER_CREATURE -> this.creatures.isEnabled();
                case MONSTER -> this.monsters.isEnabled();
                case AMBIENT, WATER_AMBIENT -> this.ambients.isEnabled();
                default -> this.others.isEnabled();
            };
        }
    }

    @EventTarget
    public void onRender3D(EventRender3D event) {
        if (mc.player != null && mc.world != null) {
            if (this.hands.isEnabled()) {
            }
        }
    }

    @Override
    public void onDisable() {
        super.onDisable();
    }

    private void renderShader(Runnable renderCallback, String shaderMode) {
    }

    private void reloadShaders() {
    }
}
