package com.tiedup.remake.bounty;

import java.util.UUID;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;

/**
 * Represents a single bounty placed on a player.
 *
 *
 * A bounty is created when a player (client) offers a reward for capturing
 * another player (target). Anyone who delivers the target to the client
 * receives the reward.
 */
public class Bounty {

    private final String id;
    private final UUID clientId;
    private final UUID targetId;
    private String clientName;
    private String targetName;
    private final ItemStack reward;
    private final long creationTime; // System.currentTimeMillis()
    private final int durationSeconds; // How long the bounty lasts

    /**
     * Create a new bounty.
     */
    public Bounty(
        UUID clientId,
        String clientName,
        UUID targetId,
        String targetName,
        ItemStack reward,
        int durationSeconds
    ) {
        this.id = UUID.randomUUID().toString();
        this.clientId = clientId;
        this.clientName = clientName;
        this.targetId = targetId;
        this.targetName = targetName;
        this.reward = reward.copy();
        this.creationTime = System.currentTimeMillis();
        this.durationSeconds = durationSeconds;
    }

    /**
     * Create a bounty from NBT data.
     */
    private Bounty(
        String id,
        UUID clientId,
        String clientName,
        UUID targetId,
        String targetName,
        ItemStack reward,
        long creationTime,
        int durationSeconds
    ) {
        this.id = id;
        this.clientId = clientId;
        this.clientName = clientName;
        this.targetId = targetId;
        this.targetName = targetName;
        this.reward = reward;
        this.creationTime = creationTime;
        this.durationSeconds = durationSeconds;
    }

    // ==================== GETTERS ====================

    public String getId() {
        return id;
    }

    public UUID getClientId() {
        return clientId;
    }

    public UUID getTargetId() {
        return targetId;
    }

    public String getClientName() {
        return clientName;
    }

    public String getTargetName() {
        return targetName;
    }

    public ItemStack getReward() {
        return reward.copy();
    }

    public int getDurationSeconds() {
        return durationSeconds;
    }

    public long getCreationTime() {
        return creationTime;
    }

    // ==================== TIME CALCULATIONS ====================

    /**
     * Get remaining time in seconds.
     */
    public int getSecondsRemaining() {
        long elapsed = (System.currentTimeMillis() - creationTime) / 1000;
        return Math.max(0, durationSeconds - (int) elapsed);
    }

    /**
     * Get remaining time as [hours, minutes].
     */
    public int[] getRemainingTime() {
        int seconds = getSecondsRemaining();
        int hours = seconds / 3600;
        int minutes = (seconds % 3600) / 60;
        return new int[] { hours, minutes };
    }

    /**
     * Check if bounty has expired.
     */
    public boolean isExpired() {
        return getSecondsRemaining() <= 0;
    }

    // ==================== PLAYER CHECKS ====================

    /**
     * Check if player is the client (creator) of this bounty.
     */
    public boolean isClient(UUID playerId) {
        return clientId.equals(playerId);
    }

    /**
     * Check if player is the target of this bounty.
     */
    public boolean isTarget(UUID playerId) {
        return targetId.equals(playerId);
    }

    /**
     * Check if bounty matches (client receives target).
     */
    public boolean matches(UUID clientId, UUID targetId) {
        return this.clientId.equals(clientId) && this.targetId.equals(targetId);
    }

    // ==================== REWARD DESCRIPTION ====================

    /**
     * Get a description of the reward (e.g., "Diamond x 5").
     */
    public String getRewardDescription() {
        if (reward.isEmpty()) {
            return "Nothing";
        }
        return reward.getHoverName().getString() + " x " + reward.getCount();
    }

    // ==================== NAME UPDATES ====================

    /**
     * Update client name (for when player was offline during creation).
     */
    public void setClientName(String name) {
        this.clientName = name;
    }

    /**
     * Update target name (for when player was offline during creation).
     */
    public void setTargetName(String name) {
        this.targetName = name;
    }

    // ==================== NBT SERIALIZATION ====================

    public CompoundTag save() {
        CompoundTag tag = new CompoundTag();
        tag.putString("id", id);
        tag.putUUID("clientId", clientId);
        tag.putUUID("targetId", targetId);
        tag.putString("clientName", clientName);
        tag.putString("targetName", targetName);
        tag.put("reward", reward.save(new CompoundTag()));
        tag.putLong("creationTime", creationTime);
        tag.putInt("durationSeconds", durationSeconds);
        return tag;
    }

    public static Bounty load(CompoundTag tag) {
        return new Bounty(
            tag.getString("id"),
            tag.getUUID("clientId"),
            tag.getString("clientName"),
            tag.getUUID("targetId"),
            tag.getString("targetName"),
            ItemStack.of(tag.getCompound("reward")),
            tag.getLong("creationTime"),
            tag.getInt("durationSeconds")
        );
    }
}
