package com.tiedup.remake.state;

import com.tiedup.remake.entities.LeashProxyEntity;
import net.minecraft.world.entity.Entity;

/**
 * Interface for accessing leash-related fields injected into ServerPlayer via mixin.
 * Cast any ServerPlayer to this interface to access leash functionality.
 *
 * NOTE: This interface is in a separate package from mixins because mixin packages
 * cannot be referenced directly from regular code.
 *
 * Usage:
 * <pre>
 * if (player instanceof IPlayerLeashAccess access) {
 *     access.tiedup$attachLeash(masterEntity);
 * }
 * </pre>
 */
public interface IPlayerLeashAccess {
    /**
     * Attach a leash from this player to a holder entity.
     * Creates a LeashProxyEntity if not already present.
     *
     * @param holder The entity holding the leash (master player, NPC, or fence knot)
     */
    void tiedup$attachLeash(Entity holder);

    /**
     * Detach the leash from this player.
     * Discards the LeashProxyEntity.
     */
    void tiedup$detachLeash();

    /**
     * Drop a lead item when detaching.
     */
    void tiedup$dropLeash();

    /**
     * Check if this player is currently leashed.
     *
     * @return true if leashed to an entity
     */
    boolean tiedup$isLeashed();

    /**
     * Get the entity holding this player's leash.
     *
     * @return The leash holder, or null if not leashed
     */
    Entity tiedup$getLeashHolder();

    /**
     * Get the proxy entity used for leash rendering.
     *
     * @return The LeashProxyEntity, or null if not leashed
     */
    LeashProxyEntity tiedup$getLeashProxy();

    /**
     * Tick the leash system - check validity and apply traction.
     * Called from Forge TickEvent.PlayerTickEvent.
     */
    void tiedup$tickLeash();

    /**
     * Set extra slack on the leash (increases pull start and max distances).
     * Used during "pet leads" dogwalk so the player can walk ahead without being yanked back.
     *
     * @param slack Extra distance in blocks (0.0 = no slack)
     */
    void tiedup$setLeashSlack(double slack);

    /**
     * Get the current leash slack value.
     *
     * @return Extra slack distance in blocks
     */
    double tiedup$getLeashSlack();
}
