package com.tiedup.remake.network.sync;

import java.util.UUID;

/**
 * Represents a pending synchronization entry for a player that wasn't loaded yet.
 * Stores the data needed to retry the sync later.
 */
public class PendingSyncEntry {

    private final SyncType type;
    private final UUID targetPlayerUUID;
    private final long creationTick;
    private int retryCount;

    // Data for BIND_STATE sync
    private final byte stateFlags;

    // Data for ENSLAVEMENT sync
    private final UUID masterUUID;
    private final UUID transportUUID;
    private final boolean isEnslaved;

    /**
     * Create a pending bind state sync entry.
     */
    public static PendingSyncEntry forBindState(
        UUID targetUUID,
        byte flags,
        long currentTick
    ) {
        return new PendingSyncEntry(
            SyncType.BIND_STATE,
            targetUUID,
            currentTick,
            flags,
            null,
            null,
            false
        );
    }

    /**
     * Create a pending enslavement sync entry.
     */
    public static PendingSyncEntry forEnslavement(
        UUID targetUUID,
        UUID masterUUID,
        UUID transportUUID,
        boolean isEnslaved,
        long currentTick
    ) {
        return new PendingSyncEntry(
            SyncType.ENSLAVEMENT,
            targetUUID,
            currentTick,
            (byte) 0,
            masterUUID,
            transportUUID,
            isEnslaved
        );
    }

    private PendingSyncEntry(
        SyncType type,
        UUID targetUUID,
        long creationTick,
        byte stateFlags,
        UUID masterUUID,
        UUID transportUUID,
        boolean isEnslaved
    ) {
        this.type = type;
        this.targetPlayerUUID = targetUUID;
        this.creationTick = creationTick;
        this.retryCount = 0;
        this.stateFlags = stateFlags;
        this.masterUUID = masterUUID;
        this.transportUUID = transportUUID;
        this.isEnslaved = isEnslaved;
    }

    public SyncType getType() {
        return type;
    }

    public UUID getTargetPlayerUUID() {
        return targetPlayerUUID;
    }

    public long getCreationTick() {
        return creationTick;
    }

    public int getRetryCount() {
        return retryCount;
    }

    public void incrementRetryCount() {
        retryCount++;
    }

    /**
     * Check if this entry has expired (too many retries or too old).
     * @param currentTick The current game tick
     * @param maxTicks Maximum age in ticks before expiring
     * @param maxRetries Maximum retry attempts
     * @return true if expired and should be discarded
     */
    public boolean isExpired(long currentTick, int maxTicks, int maxRetries) {
        return (
            (currentTick - creationTick) > maxTicks || retryCount >= maxRetries
        );
    }

    // Getters for sync data

    public byte getStateFlags() {
        return stateFlags;
    }

    public UUID getMasterUUID() {
        return masterUUID;
    }

    public UUID getTransportUUID() {
        return transportUUID;
    }

    public boolean isEnslaved() {
        return isEnslaved;
    }
}
