package com.tiedup.remake.tasks;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.network.ModNetwork;
import com.tiedup.remake.network.action.PacketForceFeeding;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.state.PlayerBindState;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;

/**
 * Server-side task for force feeding a gagged entity.
 * Player must keep looking at the target for 5 seconds to complete.
 */
public class ForceFeedingTask extends TimedInteractTask {

    private Player feeder;
    private ItemStack foodStack;
    private int sourceSlot;

    public ForceFeedingTask(
        IBondageState targetState,
        LivingEntity targetEntity,
        int seconds,
        Level level,
        Player feeder,
        ItemStack foodStack,
        int sourceSlot
    ) {
        super(targetState, targetEntity, seconds, level);
        this.feeder = feeder;
        this.foodStack = foodStack.copy();
        this.sourceSlot = sourceSlot;
    }

    public void setFeeder(Player feeder) {
        this.feeder = feeder;
    }

    @Override
    public synchronized void update() {
        // Cancel if feeder is gone or dead
        if (feeder == null || !feeder.isAlive() || feeder.isRemoved()) {
            stop();
            return;
        }

        if (targetEntity != null) {
            double distance = feeder.distanceTo(targetEntity);
            if (distance > 4.0) {
                TiedUpMod.LOGGER.debug(
                    "[ForceFeedingTask] Feeder {} moved too far from target ({} blocks), cancelling",
                    feeder.getName().getString(),
                    String.format("%.1f", distance)
                );
                stop();
                return;
            }

            if (!feeder.hasLineOfSight(targetEntity)) {
                TiedUpMod.LOGGER.debug(
                    "[ForceFeedingTask] Feeder {} lost line of sight to target, cancelling",
                    feeder.getName().getString()
                );
                stop();
                return;
            }
        }

        super.update();
    }

    @Override
    protected void onComplete() {
        if (!isTargetValid()) {
            TiedUpMod.LOGGER.warn(
                "[ForceFeedingTask] Target entity no longer valid, cancelling task"
            );
            stop();
            return;
        }

        if (feeder == null || !feeder.isAlive()) {
            TiedUpMod.LOGGER.warn(
                "[ForceFeedingTask] Feeder no longer valid, cancelling task"
            );
            stop();
            return;
        }

        // Validate the item in the source slot is still edible
        ItemStack slotStack = feeder.getInventory().getItem(sourceSlot);
        if (slotStack.isEmpty() || !slotStack.getItem().isEdible()) {
            TiedUpMod.LOGGER.warn(
                "[ForceFeedingTask] Food item no longer in slot {}, cancelling",
                sourceSlot
            );
            stop();
            return;
        }

        TiedUpMod.LOGGER.info(
            "[ForceFeedingTask] Force feeding complete for {}",
            targetEntity.getName().getString()
        );

        if (targetEntity instanceof Player targetPlayer) {
            // Feed the player using vanilla eat mechanics
            targetPlayer.eat(targetPlayer.level(), slotStack.copy());
            slotStack.shrink(1);
        } else if (targetEntity instanceof EntityDamsel damsel) {
            // Use existing NPC feed method (handles shrink internally)
            damsel.feedByPlayer(feeder, slotStack);
        }

        // Play eating sound at target
        targetEntity
            .level()
            .playSound(
                null,
                targetEntity.getX(),
                targetEntity.getY(),
                targetEntity.getZ(),
                SoundEvents.GENERIC_EAT,
                SoundSource.PLAYERS,
                1.0F,
                1.0F
            );

        // Send messages
        String targetName = targetEntity.getName().getString();
        String feederName = feeder.getName().getString();

        if (feeder instanceof ServerPlayer serverFeeder) {
            serverFeeder.displayClientMessage(
                Component.translatable(
                    "msg.tiedup.forcefeeding.you_fed", targetName
                ).withStyle(ChatFormatting.GRAY),
                true
            );
        }

        if (targetEntity instanceof ServerPlayer serverTarget) {
            serverTarget.displayClientMessage(
                Component.translatable("msg.tiedup.forcefeeding.been_fed")
                    .withStyle(ChatFormatting.GRAY),
                true
            );
        }

        stop();

        // Send completion packets (stateInfo = -1)
        if (targetEntity instanceof ServerPlayer serverTarget) {
            PacketForceFeeding completionPacket = new PacketForceFeeding(
                -1,
                this.getMaxSeconds(),
                false,
                feederName
            );
            ModNetwork.sendToPlayer(completionPacket, serverTarget);
        }

        if (feeder instanceof ServerPlayer serverFeeder) {
            PacketForceFeeding completionPacket = new PacketForceFeeding(
                -1,
                this.getMaxSeconds(),
                true,
                targetName
            );
            ModNetwork.sendToPlayer(completionPacket, serverFeeder);
        }
    }

    @Override
    public void sendProgressPackets() {
        if (stopped) return;

        String feederName =
            feeder != null ? feeder.getName().getString() : "Someone";
        String targetName = targetEntity.getName().getString();

        // Packet to target (if player): isActiveRole=false, shows feeder's name
        if (targetEntity instanceof ServerPlayer serverTarget) {
            PacketForceFeeding victimPacket = new PacketForceFeeding(
                this.getState(),
                this.getMaxSeconds(),
                false,
                feederName
            );
            ModNetwork.sendToPlayer(victimPacket, serverTarget);
        }

        // Packet to feeder: isActiveRole=true, shows target's name
        if (feeder instanceof ServerPlayer serverFeeder) {
            PacketForceFeeding feederPacket = new PacketForceFeeding(
                this.getState(),
                this.getMaxSeconds(),
                true,
                targetName
            );
            ModNetwork.sendToPlayer(feederPacket, serverFeeder);
        }
    }

    @Override
    public void setUpTargetState() {
        // Server-side: nothing to do - client handles its own PlayerStateTask via packets
    }
}
