package com.tiedup.remake.items.base;

import com.tiedup.remake.state.IBondageState;
import com.tiedup.remake.util.KidnappedHelper;
import com.tiedup.remake.v2.BodyRegionV2;
import java.util.List;
import java.util.UUID;
import net.minecraft.ChatFormatting;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;

/**
 * Base class for items that maintain a relationship between an owner and a target.
 * This is used for "pairing" mechanics like shocker controllers and GPS locators.
 *
 * <p>Data is stored directly in the ItemStack's NBT tag using UUIDs for reliability
 * and Names for display in tooltips.</p>
 */
public abstract class ItemOwnerTarget extends Item {

    public ItemOwnerTarget(Properties properties) {
        super(properties);
    }

    /**
     * Links this item to a specific owner.
     * @param stack The item instance
     * @param owner The player who now owns this tool
     */
    public void setOwner(ItemStack stack, Player owner) {
        if (owner != null) {
            CompoundTag nbt = stack.getOrCreateTag();
            nbt.putUUID("ownerId", owner.getUUID());
            nbt.putString("ownerName", owner.getName().getString());
        }
    }

    /**
     * Directly sets the owner UUID without a player instance.
     */
    public void setOwnerId(ItemStack stack, UUID uuid) {
        if (uuid != null) {
            stack.getOrCreateTag().putUUID("ownerId", uuid);
        }
    }

    /**
     * Clears all ownership data from the item.
     */
    public void removeOwner(ItemStack stack) {
        CompoundTag nbt = stack.getTag();
        if (nbt != null) {
            nbt.remove("ownerId");
            nbt.remove("ownerName");
        }
    }

    /**
     * Links this tool to a specific target (victim/slave).
     * Used for TARGETED mode in shockers and locators.
     */
    public void setTarget(ItemStack stack, Entity target) {
        if (target != null) {
            CompoundTag nbt = stack.getOrCreateTag();
            nbt.putUUID("targetId", target.getUUID());
            nbt.putString("targetName", target.getName().getString());
        }
    }

    /**
     * Retrieves the stored owner UUID.
     * @return UUID or null if unclaimed
     */
    public UUID getOwnerId(ItemStack stack) {
        CompoundTag nbt = stack.getTag();
        if (nbt != null && nbt.hasUUID("ownerId")) {
            return nbt.getUUID("ownerId");
        }
        return null;
    }

    /**
     * Retrieves the stored owner name for display purposes.
     */
    public String getOwnerName(ItemStack stack) {
        CompoundTag nbt = stack.getTag();
        if (nbt != null && nbt.contains("ownerName")) {
            return nbt.getString("ownerName");
        }
        return null;
    }

    /**
     * Retrieves the stored target UUID.
     */
    public UUID getTargetId(ItemStack stack) {
        CompoundTag nbt = stack.getTag();
        if (nbt != null && nbt.hasUUID("targetId")) {
            return nbt.getUUID("targetId");
        }
        return null;
    }

    /**
     * Retrieves the stored target name.
     */
    public String getTargetName(ItemStack stack) {
        CompoundTag nbt = stack.getTag();
        if (nbt != null && nbt.contains("targetName")) {
            return nbt.getString("targetName");
        }
        return null;
    }

    public boolean hasOwner(ItemStack stack) {
        return getOwnerId(stack) != null;
    }

    public boolean hasTarget(ItemStack stack) {
        return getTargetId(stack) != null;
    }

    /**
     * Verification if the current player matches the item's stored owner.
     */
    public boolean isOwner(ItemStack stack, Player player) {
        return player != null && isOwner(stack, player.getUUID());
    }

    public boolean isOwner(ItemStack stack, UUID uuid) {
        if (uuid != null && stack != null) {
            UUID ownerUUID = getOwnerId(stack);
            return uuid.equals(ownerUUID);
        }
        return false;
    }

    /**
     * Check if a player instance matches the item's current target.
     */
    // TOOLTIP HELPERS

    /**
     * Appends the "Owner: ..." or "Unclaimed (...)" tooltip line.
     * @param unclaimedHint text shown when unclaimed (e.g. "Right-click a player")
     */
    protected void appendOwnerTooltip(
        ItemStack stack,
        List<Component> tooltip,
        String unclaimedHint
    ) {
        if (hasOwner(stack)) {
            tooltip.add(
                Component.translatable("item.tiedup.owner_target.owner")
                    .withStyle(ChatFormatting.GOLD)
                    .append(
                        Component.literal(getOwnerName(stack)).withStyle(
                            ChatFormatting.WHITE
                        )
                    )
            );
        } else {
            tooltip.add(
                Component.translatable(
                    "item.tiedup.owner_target.unclaimed", unclaimedHint
                ).withStyle(ChatFormatting.GRAY)
            );
        }
    }

    /**
     * Resolves the display name for the current target, enriching it with
     * the collar nickname if available.
     * @return display name, possibly "Nickname (RealName)" if collar has a nickname
     */
    protected String resolveTargetDisplayName(
        ItemStack stack,
        @Nullable Level level
    ) {
        String displayName = getTargetName(stack);
        if (level != null && hasTarget(stack)) {
            Player target = level.getPlayerByUUID(getTargetId(stack));
            if (target != null) {
                IBondageState targetState = KidnappedHelper.getKidnappedState(
                    target
                );
                if (targetState != null && targetState.hasCollar()) {
                    ItemStack collar = targetState.getEquipment(
                        BodyRegionV2.NECK
                    );
                    if (
                        com.tiedup.remake.v2.bondage.CollarHelper.isCollar(collar) &&
                        com.tiedup.remake.v2.bondage.CollarHelper.hasNickname(collar)
                    ) {
                        displayName =
                            com.tiedup.remake.v2.bondage.CollarHelper.getNickname(collar) +
                            " (" +
                            displayName +
                            ")";
                    }
                }
            }
        }
        return displayName;
    }

    public boolean isTarget(ItemStack stack, Player potentialTarget) {
        if (potentialTarget != null && stack != null) {
            UUID playerUUID = potentialTarget.getUUID();
            UUID targetUUID = getTargetId(stack);
            return (
                playerUUID != null &&
                targetUUID != null &&
                playerUUID.equals(targetUUID)
            );
        }
        return false;
    }
}
