package jesse.keeblarcraft.AttributeMgr.AttributeNodes.FactionNodes;

import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode;
import jesse.keeblarcraft.FactionMgr.FactionTier;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerInBaseCallback;
import jesse.keeblarcraft.FactionMgr.FactionTier.FactionTierEnum;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;

public class FactionBeacon extends AbstractNode {
    private int beaconStrength = 1; // Increases with faction power; 1 is default
    private int potionEffectLastingTimeTicks = 200; // 20 ticks per second makes this 10 seconds
    private Integer timerLengthMillis = 5000; // The default potion length is 10 seconds; so reset every 5 to be sure!
    private Boolean resetTimer = true;
    private Timer timer = new Timer();
    @Override
    public String GetNodeTitle() {
        return "faction_beacon";
    }

    @Override
    public String GetNodeDescription() {
        return "This is a great unlockable for any faction to have and is leveled up with higher faction power. Gives beacon-like abilities + more!";
    }

    @Override
    public HashMap<String, List<String>> GetDetails() {
        HashMap<String, List<String>> ret = new HashMap<String, List<String>>();
        ret.put("Faction Beacon", List.of("Grants a ton of beacon-like effects on faction members inside the radius of the faction block"));
        return ret;
    }

    private Integer GetBeaconAmplifier(FactionTierEnum tier) {
        switch (tier) {
            case TIER_I:
            case TIER_II:
                beaconStrength = 0;
                break;
            case TIER_III:
                beaconStrength = 1;
                break;
            case TIER_IV:
                beaconStrength = 2;
                break;
            case TIER_V:
                beaconStrength = 3;
                break;
            case TIER_VI:
                beaconStrength = 8;
                break;
            default:
                // Invalid case; in which case the beacon probably should do nothing
                beaconStrength = 0;
                break;
        }
        return beaconStrength;
    }

    private void ApplyEffects(ServerPlayerEntity player, FactionTierEnum tier) {
        // player.setAbsorptionAmount(absorptionAmnt);
        // Duration is in ticks
        beaconStrength = GetBeaconAmplifier(tier);

        // Tier 2 effects
        if (FactionTier.IsGreaterOrEqualTo(tier, FactionTierEnum.TIER_II)) {
            StatusEffectInstance regen = new StatusEffectInstance(StatusEffects.REGENERATION, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            StatusEffectInstance fire = new StatusEffectInstance(StatusEffects.FIRE_RESISTANCE, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            player.addStatusEffect(regen);
            player.addStatusEffect(fire);
        }

        // Tier 3 effects
        if (FactionTier.IsGreaterOrEqualTo(tier, FactionTierEnum.TIER_III)) {
            StatusEffectInstance hero = new StatusEffectInstance(StatusEffects.HERO_OF_THE_VILLAGE, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            StatusEffectInstance haste = new StatusEffectInstance(StatusEffects.HASTE, potionEffectLastingTimeTicks, beaconStrength, true, true, true);

            player.addStatusEffect(hero);
            player.addStatusEffect(haste);
        }

        // Tier 4 effects
        if (FactionTier.IsGreaterOrEqualTo(tier, FactionTierEnum.TIER_IV)) {
            StatusEffectInstance conduit = new StatusEffectInstance(StatusEffects.CONDUIT_POWER, potionEffectLastingTimeTicks, 0, true,true, true);
            StatusEffectInstance luck = new StatusEffectInstance(StatusEffects.LUCK, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            StatusEffectInstance absorption = new StatusEffectInstance(StatusEffects.ABSORPTION, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            StatusEffectInstance waterBreathing = new StatusEffectInstance(StatusEffects.WATER_BREATHING, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            player.addStatusEffect(conduit);
            player.addStatusEffect(luck);
            player.addStatusEffect(absorption);
            player.addStatusEffect(waterBreathing);
        }

        // Tier 5 effects
        if (FactionTier.IsGreaterOrEqualTo(tier, FactionTierEnum.TIER_V)) {
            StatusEffectInstance resistance = new StatusEffectInstance(StatusEffects.RESISTANCE, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            StatusEffectInstance strength = new StatusEffectInstance(StatusEffects.STRENGTH, potionEffectLastingTimeTicks, beaconStrength, true, true, true);
            StatusEffectInstance dolphins = new StatusEffectInstance(StatusEffects.DOLPHINS_GRACE, potionEffectLastingTimeTicks, beaconStrength, true, true, true);

            player.addStatusEffect(resistance);
            player.addStatusEffect(strength);
            player.addStatusEffect(dolphins);
        }

        // Tier 6 effects
        if (FactionTier.IsGreaterOrEqualTo(tier, FactionTierEnum.TIER_VI)) {
            StatusEffectInstance freeHealth = new StatusEffectInstance(StatusEffects.HEALTH_BOOST, potionEffectLastingTimeTicks, beaconStrength, true, true, true);

            player.addStatusEffect(freeHealth);
        }
    }

    @Override
    public void RegisterCallbacks() {
        PlayerInBaseCallback.EVENT.register((player, world, power, factionTier) -> {
            if (resetTimer) {
                // The timer is super necessary because some effects (like regen) will not actually regen the player unless they can run for a few seconds
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        ApplyEffects((ServerPlayerEntity) player, factionTier);
                        resetTimer = true;
                    }

                }, timerLengthMillis);
                resetTimer = false;
            }
            return ActionResult.PASS;
        });
    }

}
