package com.r3944realms.leashedplayer.content.entities;

import com.r3944realms.leashedplayer.LeashedPlayer;
import com.r3944realms.leashedplayer.config.LeashPlayerCommonConfig;
import com.r3944realms.leashedplayer.content.items.ModItemRegister;
import io.github.kunosayo.nestle.entity.NestleLeadNormalEntity;
import io.github.kunosayo.nestle.entity.NestleLeadPlayerEntity;
import io.github.kunosayo.nestle.entity.data.NestleLeadData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.EntityHitResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class NestleRopeArrow extends AbstractArrow {
    private static final int maxLifeTime = LeashPlayerCommonConfig.TheNestleArrowMaxLifeTime.get();
    protected NestleRopeArrow(EntityType<? extends AbstractArrow> pEntityType, Level pLevel) {
        super(pEntityType, pLevel);
    }
    public NestleRopeArrow(EntityType<? extends AbstractArrow> entityType, double pX, double pY, double pZ, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon, @Nullable ServerPlayer serverPlayer) {
        super(entityType, pX, pY, pZ, pLevel, pPickupItemStack, pFiredFromWeapon);
        if (serverPlayer != null && !level().isClientSide) {
            if(serverPlayer.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) {
                nestleRopeArrow.removePassenger(serverPlayer);//重置先前的箭矢
                nestleRopeArrow.setOwner(null);
            }
            serverPlayer.startRiding(this);
            this.setOwner(serverPlayer);
        } else this.setOwner(null);
    }

    public NestleRopeArrow(EntityType<? extends AbstractArrow> entityType, LivingEntity pOwner, Level pLevel, ItemStack pPickupItemStack, @Nullable ItemStack pFiredFromWeapon) {
        super(entityType, pOwner, pLevel, pPickupItemStack, pFiredFromWeapon);
        if (!level().isClientSide) {
            if(pOwner.getVehicle() instanceof NestleRopeArrow nestleRopeArrow) {
                nestleRopeArrow.removePassenger(pOwner);//重置先前的箭矢
                nestleRopeArrow.setOwner(null);
            }
            pOwner.startRiding(this);
            this.setOwner(pOwner);
        }
    }

    @Override
    protected @NotNull ItemStack getDefaultPickupItem() {
        return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance();
    }
    protected ItemStack getOrginalItemStack() {
        return Items.ARROW.getDefaultInstance();
    }
    protected ItemStack getSelfItemStack() {
        return ModItemRegister.NESTLE_ROPE_ARROW.get().getDefaultInstance();
    }
    protected void hitOnEntityHandler(Entity pEntity) {
        //NOOP
    }
    @Override
    public void setOwner(@Nullable Entity pEntity) {
        boolean isNull = pEntity == null;
        this.ownerUUID = isNull ? null : pEntity.getUUID();
        this.cachedOwner = isNull ? null : pEntity;
        this.pickup = this.pickup == Pickup.CREATIVE_ONLY ? this.pickup : Pickup.DISALLOWED;
    }

    @Override
    protected void tickDespawn() {
        this.life++;
        if (this.life >= maxLifeTime) {
            ItemEntity nestle_arrow_item = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getSelfItemStack());
            this.level().addFreshEntity(nestle_arrow_item);
            this.discard();
        }
    }

    @Override
    protected boolean tryPickup(@NotNull Player pPlayer) {
        if (life <= 40)
            return false;
        else {
            this.pickup = Pickup.ALLOWED;
        }
        return super.tryPickup(pPlayer);
    }

    @Override
    public void tick() {
        super.tick();
        Entity owner = getOwner();
        if (owner != null && !owner.level().isClientSide) {
            if (!inGround) {
                if (owner.getVehicle() == null) owner.startRiding(this);
            }
            else {
                owner.stopRiding();
                setOwner(null);
            }
        }
        if (this.inGround && this.inGroundTime != 0) {
            this.level().broadcastEntityEvent(this, (byte)0);
            this.setPickupItemStack(new ItemStack(getSelfItemStack().getItem()));
        }
    }

    @Override
    protected void onHitEntity(@NotNull EntityHitResult pResult) {
       if(!level().isClientSide) {
           Entity entity = pResult.getEntity();
           hitOnEntityHandler(entity);
           Entity owner = this.getOwner();
           if (owner == null && entity instanceof Player player) {
               this.setOwner(player);
           }
           else if (owner != null && entity != owner ) {
              if (entity instanceof LivingEntity livingEntity && LeashedPlayer.IS_NESTLE_LOADED) {//保证即使没Nestle 也不会导致使用该物品会抛异常
                  ItemEntity arrow = new ItemEntity(this.level(), this.position().x, this.position().y, this.position().z, getOrginalItemStack());
                  if (livingEntity instanceof Player player) {
                      if (NestleLeadData.isNestle(player, livingEntity)) {
                          arrow.setItem(getSelfItemStack());
                      } else {
                          NestleLeadData.nestleTwo((Player) owner, player);
                          NestleLeadPlayerEntity.inParamFrom = player.getUUID();
                          NestleLeadPlayerEntity.inParamTarget = entity.getUUID();
                          NestleLeadPlayerEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT);
                      }
                  } else {
                      Player player = (Player) owner;
                      if (NestleLeadData.isNestle(player, livingEntity)) {
                          arrow.setItem(getSelfItemStack());
                      } else {
                          NestleLeadData.nestleTwo(player, livingEntity);
                          NestleLeadNormalEntity.inParamFrom = player;
                          NestleLeadNormalEntity.inParamTarget = livingEntity;
                          NestleLeadNormalEntity.ENTITY_TYPE.spawn((ServerLevel)player.level(), player.getBlockPosBelowThatAffectsMyMovement(), MobSpawnType.EVENT);
                          NestleLeadNormalEntity.inParamFrom = null;
                          NestleLeadNormalEntity.inParamTarget = null;
                      }

                  }
                  this.level().addFreshEntity(arrow);
                  discard();
               }
           }
       }
       else super.onHitEntity(pResult);
    }
}
