package com.tiedup.remake.items;

import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.items.base.ItemOwnerTarget;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.List;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;

public class ItemGpsLocator extends ItemOwnerTarget {

    public ItemGpsLocator() {
        super(new net.minecraft.world.item.Item.Properties().stacksTo(1));
    }

    @Override
    public void appendHoverText(
        ItemStack stack,
        @Nullable Level level,
        List<Component> tooltip,
        TooltipFlag flag
    ) {
        super.appendHoverText(stack, level, tooltip, flag);

        appendOwnerTooltip(stack, tooltip, "Right-click a player");

        if (hasTarget(stack)) {
            String displayName = resolveTargetDisplayName(stack, level);
            tooltip.add(
                Component.translatable("item.tiedup.gps_locator.target", displayName)
                    .withStyle(ChatFormatting.BLUE)
            );
        }
    }

    @Override
    public InteractionResultHolder<ItemStack> use(
        Level level,
        Player player,
        InteractionHand hand
    ) {
        ItemStack stack = player.getItemInHand(hand);

        if (level.isClientSide) return InteractionResultHolder.success(stack);

        if (!hasOwner(stack)) {
            SystemMessageManager.sendToPlayer(
                player,
                SystemMessageManager.MessageCategory.ERROR,
                "You must claim this locator first! (Right-click a player)"
            );
            return InteractionResultHolder.fail(stack);
        }

        if (!isOwner(stack, player)) {
            SystemMessageManager.sendToPlayer(
                player,
                SystemMessageManager.MessageCategory.LOCATOR_NOT_OWNER
            );
            return InteractionResultHolder.fail(stack);
        }

        if (hasTarget(stack)) {
            // Use server player list for cross-dimension tracking
            Player target = level
                .getServer()
                .getPlayerList()
                .getPlayer(getTargetId(stack));
            if (target != null) {
                IBondageState targetState = KidnappedHelper.getKidnappedState(
                    target
                );
                if (targetState != null && targetState.hasCollar()) {
                    ItemStack collarStack = targetState.getEquipment(
                        BodyRegionV2.NECK
                    );
                    if (CollarHelper.hasGPS(collarStack)) {
                        if (
                            CollarHelper.isOwner(collarStack, player) ||
                            CollarHelper.hasPublicTracking(collarStack)
                        ) {
                            // Check if same dimension
                            boolean sameDimension = player
                                .level()
                                .dimension()
                                .equals(target.level().dimension());

                            if (sameDimension) {
                                double distance = player.distanceTo(target);
                                String direction = getDirection(player, target);
                                SystemMessageManager.sendToPlayer(
                                    player,
                                    SystemMessageManager.MessageCategory.LOCATOR_DETECTED,
                                    (int) distance + "m [" + direction + "]"
                                );
                            } else {
                                // Cross-dimension: show dimension name
                                String dimName = getDimensionDisplayName(
                                    target
                                        .level()
                                        .dimension()
                                        .location()
                                        .getPath()
                                );
                                SystemMessageManager.sendToPlayer(
                                    player,
                                    SystemMessageManager.MessageCategory.LOCATOR_DETECTED,
                                    "Target is in [" + dimName + "]"
                                );
                            }

                            playLocatorSound(player);
                        } else {
                            SystemMessageManager.sendToPlayer(
                                player,
                                SystemMessageManager.MessageCategory.ERROR,
                                "You are not allowed to access this GPS Collar!"
                            );
                        }
                    } else {
                        SystemMessageManager.sendToPlayer(
                            player,
                            SystemMessageManager.MessageCategory.ERROR,
                            "Target is not wearing a GPS Collar!"
                        );
                    }
                }
            } else {
                SystemMessageManager.sendToPlayer(
                    player,
                    SystemMessageManager.MessageCategory.ERROR,
                    "Unable to locate target! (Offline)"
                );
            }
        } else {
            SystemMessageManager.sendToPlayer(
                player,
                SystemMessageManager.MessageCategory.ERROR,
                "No target connected!"
            );
        }

        return InteractionResultHolder.success(stack);
    }

    /**
     */
    @Override
    public InteractionResult interactLivingEntity(
        ItemStack stack,
        Player player,
        LivingEntity target,
        InteractionHand hand
    ) {
        if (player.level().isClientSide) return InteractionResult.SUCCESS;

        IBondageState playerState = KidnappedHelper.getKidnappedState(player);
        if (
            playerState != null && playerState.isTiedUp()
        ) return InteractionResult.FAIL;

        if (!hasOwner(stack)) {
            setOwner(stack, player);
            SystemMessageManager.sendToPlayer(
                player,
                SystemMessageManager.MessageCategory.LOCATOR_CLAIMED
            );
        } else if (!isOwner(stack, player)) {
            SystemMessageManager.sendToPlayer(
                player,
                SystemMessageManager.MessageCategory.LOCATOR_NOT_OWNER
            );
            return InteractionResult.FAIL;
        }

        IBondageState targetState = KidnappedHelper.getKidnappedState(target);
        if (targetState != null) {
            setTarget(stack, target);
            player.setItemInHand(hand, stack); // Force sync
            SystemMessageManager.sendChatToPlayer(
                player,
                "Connected to " + target.getName().getString(),
                ChatFormatting.GREEN
            );
            return InteractionResult.SUCCESS;
        }

        return InteractionResult.PASS;
    }

    private String getDirection(Player source, Player target) {
        double dx = target.getX() - source.getX();
        double dz = target.getZ() - source.getZ();

        if (Math.abs(dx) > Math.abs(dz)) {
            return dx > 0 ? "EAST" : "WEST";
        } else {
            return dz > 0 ? "SOUTH" : "NORTH";
        }
    }

    private void playLocatorSound(Player player) {
        player
            .level()
            .playSound(
                null,
                player.blockPosition(),
                com.tiedup.remake.core.ModSounds.SHOCKER_ACTIVATED.get(),
                net.minecraft.sounds.SoundSource.PLAYERS,
                0.5f,
                1.0f
            );
    }

    /**
     * Get a user-friendly display name for a dimension.
     */
    private String getDimensionDisplayName(String dimensionPath) {
        return switch (dimensionPath) {
            case "overworld" -> "Overworld";
            case "the_nether" -> "The Nether";
            case "the_end" -> "The End";
            default -> dimensionPath.replace("_", " ");
        };
    }
}
