package studio.halbear.hem_custom.vehicles.Entity;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.IPacket;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.network.NetworkHooks;

public class Airboat extends Entity {
    private static final DataParameter<Float> ORIENTATION_ROLL = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> TARGET_ORIENTATION_ROLL = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ORIENTATION_YAW = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> TARGET_ORIENTATION_YAW = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ORIENTATION_PITCH = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> TARGET_ORIENTATION_PITCH = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ENGINE1_RPM = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> TARGET_ENGINE1_RPM = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ENGINE1_PROP_ANGLE = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ENGINE2_RPM = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> TARGET_ENGINE2_RPM = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ENGINE2_PROP_ANGLE = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> BALLOON_HEALTH = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> BODY_HEALTH = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ROPES_HEALTH = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> ELEVATOR_PITCH = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);
    private static final DataParameter<Float> YAW_ANGLE = EntityDataManager.createKey(Airboat.class, DataSerializers.FLOAT);

    public void SetVehicleRoll(float value){
        this.dataManager.set(ORIENTATION_ROLL, value);
    }
    public void SetVehicleYaw(float value){
        this.dataManager.set(ORIENTATION_YAW, value);
    }
    public void SetVehiclePitch(float value){
        this.dataManager.set(ORIENTATION_PITCH, value);
    }
    public float GetVehicleRoll(){
        return this.dataManager.get(ORIENTATION_ROLL);
    }
    public float GetVehicleYaw(){
        return this.dataManager.get(ORIENTATION_YAW);
    }
    public float GetVehiclePitch(){
        return this.dataManager.get(ORIENTATION_PITCH);
    }
    public void SetEngine1RPM(float value){
        this.dataManager.set(ENGINE1_RPM, value);
    }
    public void SetEngine1PROPANGLE(float value){
        this.dataManager.set(ENGINE1_PROP_ANGLE, value);
    }
    public void SetEngine2PROPANGLE(float value){
        this.dataManager.set(ENGINE2_PROP_ANGLE, value);
    }
    public float GetEngine1RPM(){return this.dataManager.get(ENGINE1_RPM);}
    public void SetEngine2RPM(float value){ this.dataManager.set(ENGINE2_RPM, value); }
    public float GetEngine2RPM(){return this.dataManager.get(ENGINE2_RPM);}
    public float GetEngine2PROPANGLE(){return this.dataManager.get(ENGINE2_PROP_ANGLE);}
    public float GetEngine1PROPANGLE(){return this.dataManager.get(ENGINE1_PROP_ANGLE);}
    public void SetBalloonHealth(float value){
        this.dataManager.set(BALLOON_HEALTH, value);
    }
    public float GetBalloonHealth(){return this.dataManager.get(BALLOON_HEALTH);}
    public void SetBodyHealth(float value){ this.dataManager.set(BODY_HEALTH, value); }
    public float GetBodyHealth(){return this.dataManager.get(BODY_HEALTH);}
    public void SetRopeHealth(float value){ this.dataManager.set(ROPES_HEALTH, value); }
    public float GetRopeHealth(){return this.dataManager.get(ROPES_HEALTH);}
    public void SetYawAngle(float value){ this.dataManager.set(YAW_ANGLE, value); }
    public float GetYawAngl(){return this.dataManager.get(YAW_ANGLE);}
    public void SetElevatorPitch(float value){ this.dataManager.set(ELEVATOR_PITCH, value); }
    public float GetElevatorPitch(){return this.dataManager.get(ELEVATOR_PITCH);}

    private static final Vector3d[] VehicleSeatOffsets = new Vector3d[]{
            new Vector3d(0.0D, -6D, 0.0D),
            new Vector3d(0.0D, -6D, 2.0D),
            new Vector3d(0.0D, -6D, -2.0D),
    };

    public Airboat(EntityType<?> entityTypeIn, World worldIn) {
        super(entityTypeIn, worldIn);
    }

    @Override
    protected void registerData() {
        this.dataManager.register(ORIENTATION_ROLL, (float)Math.floor(Math.random() * 360));
        this.dataManager.register(ORIENTATION_PITCH, (float)Math.floor(Math.random() * 360));
        this.dataManager.register(ORIENTATION_YAW, (float)Math.floor(Math.random() * 360));
        this.dataManager.register(TARGET_ORIENTATION_ROLL, 0F);
        this.dataManager.register(TARGET_ORIENTATION_YAW, 0F);
        this.dataManager.register(TARGET_ORIENTATION_PITCH, 0F);
        this.dataManager.register(ENGINE1_RPM, 0F);
        this.dataManager.register(TARGET_ENGINE1_RPM, 0F);
        this.dataManager.register(ENGINE2_RPM, 0F);
        this.dataManager.register(TARGET_ENGINE2_RPM, 0F);
        this.dataManager.register(BALLOON_HEALTH, (float)Math.floor(Math.random() * 2));
        this.dataManager.register(BODY_HEALTH, (float)Math.floor(Math.random() * 2));
        this.dataManager.register(ROPES_HEALTH, (float)Math.floor(Math.random() * 2));
        this.dataManager.register(ENGINE1_PROP_ANGLE, (float)Math.floor(Math.random() * 360));
        this.dataManager.register(ENGINE2_PROP_ANGLE, (float)Math.floor(Math.random() * 360));
        this.dataManager.register(YAW_ANGLE, -45f + (float)Math.floor(Math.random() * 91));
        this.dataManager.register(ELEVATOR_PITCH, -45f + (float)Math.floor(Math.random() * 91));
    }

    @Override
    protected void readAdditional(CompoundNBT compound) {

    }

    @Override
    protected void writeAdditional(CompoundNBT compound) {

    }

    @Override
    public IPacket<?> createSpawnPacket() {
        return NetworkHooks.getEntitySpawningPacket(this);
    }

    @Override
    public boolean canBeCollidedWith(){return true;}

    @Override
    protected boolean canFitPassenger(Entity passenger) {
        return this.getPassengers().size() < VehicleSeatOffsets.length;
    }
    @Override
    public ActionResultType processInitialInteract(PlayerEntity player, Hand hand) {
        if (this.getPassengers().size() < VehicleSeatOffsets.length && !player.isPassenger()) {
            if (!this.world.isRemote()) {
                return player.startRiding(this) ? ActionResultType.CONSUME : ActionResultType.PASS;
            }
            return ActionResultType.func_233537_a_(this.world.isRemote());
        }
        return ActionResultType.SUCCESS;
    }

    @Override
    public Entity getControllingPassenger() {
        return this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
    }

    @Override
    public void updatePassenger(Entity passenger) {
        if (this.isPassenger(passenger)) {
            int seatIndex = this.getPassengers().indexOf(passenger);
            if (seatIndex >= 0 && seatIndex < VehicleSeatOffsets.length) {
                Vector3d localOffset = VehicleSeatOffsets[seatIndex];
                Vector3d rotatedOffset = localOffset.rotateYaw((float) Math.toRadians(-this.rotationYaw));
                passenger.setPosition(
                        this.getPosX() + rotatedOffset.x,
                        this.getPosY() + rotatedOffset.y + passenger.getMountedYOffset(),
                        this.getPosZ() + rotatedOffset.z
                );
            } else {
                super.updatePassenger(passenger);
            }
        }
    }
}
