package me.km.items;

import me.km.entities.EntityItemProjectile;
import net.minecraft.block.Blocks;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BowItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.UseAction;
import net.minecraft.stats.Stats;
import net.minecraft.util.ActionResult;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.world.World;

public class ItemSling extends Item {
    public ItemSling(int maxDamage) {
        super(new Properties().defaultMaxDamage(maxDamage).group(ItemGroup.COMBAT));

        this.addPropertyOverride(new ResourceLocation("pull"), (stack, w, ent) -> {
            if(ent == null) {
                return 0.0f;
            } else {
                return ent.getActiveItemStack().getItem() != ModItems.sling ? 0.0f : (stack.getUseDuration() - ent.getItemInUseCount()) / 20.0F;
            }
        });
        this.addPropertyOverride(new ResourceLocation("pulling"), (stack, w, ent) -> ent != null && ent.isHandActive() && ent.getActiveItemStack() == stack ? 1.0f : 0.0f);
    }

    private ItemStack findAmmo(PlayerEntity p) {
        if(this.isAmmo(p.getHeldItem(Hand.OFF_HAND))) {
            return p.getHeldItem(Hand.OFF_HAND);
        } else if(this.isAmmo(p.getHeldItem(Hand.MAIN_HAND))) {
            return p.getHeldItem(Hand.MAIN_HAND);
        } else {
            for(int i = 0; i < p.inventory.getSizeInventory(); i++) {
                ItemStack stack = p.inventory.getStackInSlot(i);
                if(this.isAmmo(stack)) {
                    return stack;
                }
            }
            return ItemStack.EMPTY;
        }
    }

    private boolean isAmmo(ItemStack stack) {
        return stack.getItem() == Item.getItemFromBlock(Blocks.COBBLESTONE);
    }

    @Override
    public void onPlayerStoppedUsing(ItemStack stack, World w, LivingEntity liv, int timeLeft) {
        if(liv instanceof PlayerEntity) {
            int i = this.getUseDuration(stack) - timeLeft;
            if(i < 0) {
                return;
            }

            PlayerEntity p = (PlayerEntity) liv;
            ItemStack ammo = this.findAmmo(p);

            if(!ammo.isEmpty() || p.abilities.isCreativeMode) {
                if(ammo.isEmpty()) {
                    ammo = new ItemStack(Blocks.COBBLESTONE);
                }

                float f = BowItem.getArrowVelocity(i);
                if(f >= 0.1) {
                    if(!w.isRemote) {
                        ItemStack ammoCopy = ammo.copy();
                        ammoCopy.setCount(1);
                        EntityItemProjectile proj = new EntityItemProjectile(p, ammoCopy, 2.0f);
                        proj.setHeadingFromThrower(p, p.rotationPitch, p.rotationYaw, 0.0f, f, 1.0f);
                        stack.damageItem(1, p, (c) -> {
                        });
                        w.addEntity(proj);
                    }

                    w.playSound(null, p.getPosX(), p.getPosY(), p.getPosZ(), SoundEvents.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0f, 1.0f / (random.nextFloat() * 0.4f + 1.2f) + f * 0.5f);
                    if(!p.abilities.isCreativeMode) {
                        ammo.shrink(1);
                        if(ammo.isEmpty()) {
                            p.inventory.deleteStack(ammo);
                        }
                    }

                    p.addStat(Stats.ITEM_USED.get(this));
                }
            }
        }
    }

    @Override
    public int getUseDuration(ItemStack stack) {
        return 72000;
    }

    @Override
    public UseAction getUseAction(ItemStack stack) {
        return UseAction.BOW;
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World w, PlayerEntity p, Hand hand) {
        ItemStack ammo = p.getHeldItem(hand);
        if(!p.abilities.isCreativeMode && this.findAmmo(p).isEmpty()) {
            return new ActionResult<>(ActionResultType.FAIL, ammo);
        }
        p.setActiveHand(hand);
        return new ActionResult<>(ActionResultType.SUCCESS, ammo);
    }

    @Override
    public int getItemEnchantability() {
        return 1;
    }
}
