package com.tiedup.remake.tasks;

import com.tiedup.remake.util.time.Timer;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

/**
 *
 * Based on original PlayerStateTask from 1.12.2
 *
 * This is used on the CLIENT SIDE ONLY to track the progress of
 * tying/untying tasks for GUI display (progress bars, messages, etc.).
 *
 * The server sends progress updates via packets, and this class
 * stores them and auto-expires if updates stop coming.
 */
@OnlyIn(Dist.CLIENT)
public class PlayerStateTask {

    private final int maxState; // Total time in seconds
    private Timer timerOutdating; // Auto-expiration timer (3 seconds)
    private int state; // Current elapsed time in seconds

    // Role info for progress bar display
    private final boolean isKidnapper; // true = doing the tying, false = being tied
    private final String otherEntityName; // Name of the other party

    // Outdating timeout: 3 seconds (60 ticks)
    // Slightly longer than server's 2 seconds to account for network delay
    private static final int OUTDATING_TIMEOUT_SECONDS = 3;

    /**
     * Create a new client-side task state.
     *
     * @param maxState Total duration in seconds
     */
    public PlayerStateTask(int maxState) {
        this(maxState, false, null);
    }

    /**
     * Create a new client-side task state with role info.
     *
     * @param maxState Total duration in seconds
     * @param isKidnapper true if this player is doing the tying
     * @param otherEntityName Name of the other party
     */
    public PlayerStateTask(
        int maxState,
        boolean isKidnapper,
        String otherEntityName
    ) {
        this.maxState = maxState;
        this.state = 0;
        this.isKidnapper = isKidnapper;
        this.otherEntityName = otherEntityName;
        this.timerOutdating = new Timer(
            OUTDATING_TIMEOUT_SECONDS,
            Minecraft.getInstance().level
        );
    }

    /**
     * Update the task progress.
     * Called when receiving a progress packet from the server.
     *
     * @param state Current elapsed time in seconds
     */
    public synchronized void update(int state) {
        this.state = state;
        // Reset outdating timer (we received an update from server)
        this.timerOutdating = new Timer(
            OUTDATING_TIMEOUT_SECONDS,
            Minecraft.getInstance().level
        );
    }

    /**
     * Check if this task state has become outdated.
     * A task is outdated if we haven't received an update for 3 seconds.
     *
     * @return true if outdated
     */
    public boolean isOutdated() {
        return timerOutdating != null && timerOutdating.isExpired();
    }

    /**
     * Get the current progress state (elapsed time).
     *
     * @return Elapsed seconds
     */
    public int getState() {
        return state;
    }

    /**
     * Get the maximum duration.
     *
     * @return Total seconds
     */
    public int getMaxState() {
        return maxState;
    }

    /**
     * Get progress as a percentage (0.0 to 1.0).
     *
     * @return Progress percentage
     */
    public float getProgress() {
        if (maxState <= 0) {
            return 0.0f;
        }
        return Math.min(1.0f, (float) state / (float) maxState);
    }

    /**
     * Get remaining seconds.
     *
     * @return Remaining seconds
     */
    public int getRemaining() {
        return Math.max(0, maxState - state);
    }

    /**
     * Check if this player is the kidnapper (doing the tying).
     *
     * @return true if kidnapper, false if victim
     */
    public boolean isKidnapper() {
        return isKidnapper;
    }

    /**
     * Get the name of the other party (target if kidnapper, kidnapper if victim).
     *
     * @return Other entity name, or null if unknown
     */
    public String getOtherEntityName() {
        return otherEntityName;
    }
}
