package fr.luc.gamingcore.model;

import java.util.Objects;
import java.util.UUID;

/**
 * Représente un joueur membre d'une guilde.
 */
public class GuildMember {

    private final UUID playerUuid;
    private final UUID guildId;
    private String rankId;
    private final long joinedAt;
    private long lastOnline;
    private double contributedMoney;

    /**
     * Constructeur d'un membre de guilde.
     *
     * @param playerUuid       Identifiant UUID du joueur.
     * @param guildId          Identifiant UUID de la guilde.
     * @param rankId           Identifiant du rang occupé par le membre.
     * @param joinedAt         Horodatage en millisecondes de l'adhésion à la guilde.
     * @param lastOnline       Horodatage en millisecondes de la dernière connexion.
     * @param contributedMoney Montant total d'argent déposé par ce joueur dans la banque de guilde.
     */
    public GuildMember(UUID playerUuid, UUID guildId, String rankId, long joinedAt, long lastOnline, double contributedMoney) {
        this.playerUuid = Objects.requireNonNull(playerUuid, "Le UUID du joueur ne peut pas être nul.");
        this.guildId = Objects.requireNonNull(guildId, "Le UUID de la guilde ne peut pas être nul.");
        this.rankId = Objects.requireNonNull(rankId, "Le rangId ne peut pas être nul.");
        this.joinedAt = joinedAt > 0 ? joinedAt : System.currentTimeMillis();
        this.lastOnline = lastOnline > 0 ? lastOnline : System.currentTimeMillis();
        this.contributedMoney = Math.max(0.0, contributedMoney);
    }

    /**
     * Obtient le UUID du joueur.
     *
     * @return L'UUID unique du joueur.
     */
    public UUID getPlayerUuid() {
        return playerUuid;
    }

    /**
     * Obtient le UUID de la guilde à laquelle le membre appartient.
     *
     * @return L'UUID de la guilde.
     */
    public UUID getGuildId() {
        return guildId;
    }

    /**
     * Obtient l'identifiant du rang du membre.
     *
     * @return L'ID du rang.
     */
    public String getRankId() {
        return rankId;
    }

    /**
     * Modifie le rang du membre au sein de sa guilde.
     *
     * @param rankId Le nouvel identifiant de rang.
     */
    public void setRankId(String rankId) {
        this.rankId = Objects.requireNonNull(rankId, "Le rangId ne peut pas être nul.");
    }

    /**
     * Obtient la date et l'heure d'adhésion du membre en millisecondes.
     *
     * @return Timestamp d'arrivée dans la guilde.
     */
    public long getJoinedAt() {
        return joinedAt;
    }

    /**
     * Obtient la date et l'heure de dernière connexion connue en millisecondes.
     *
     * @return Timestamp de dernière présence.
     */
    public long getLastOnline() {
        return lastOnline;
    }

    /**
     * Met à jour l'horodatage de dernière connexion du membre.
     *
     * @param lastOnline Nouveau timestamp.
     */
    public void setLastOnline(long lastOnline) {
        this.lastOnline = lastOnline;
    }

    /**
     * Obtient la somme totale déposée par le membre dans la banque de guilde depuis son arrivée.
     *
     * @return Montant d'argent total contribué.
     */
    public double getContributedMoney() {
        return contributedMoney;
    }

    /**
     * Ajoute une somme au montant total des contributions financières du membre.
     *
     * @param amount Montant positif à ajouter.
     */
    public void addContribution(double amount) {
        if (amount > 0) {
            this.contributedMoney += amount;
        }
    }

    /**
     * Récupère l'instance Bukkit {@link org.bukkit.OfflinePlayer} correspondant au membre.
     *
     * @return L'instance OfflinePlayer.
     */
    public org.bukkit.OfflinePlayer getOfflinePlayer() {
        return org.bukkit.Bukkit.getOfflinePlayer(playerUuid);
    }

    /**
     * Récupère l'instance Bukkit {@link org.bukkit.entity.Player} si le joueur est actuellement connecté.
     *
     * @return L'instance Player ou null si déconnecté.
     */
    public org.bukkit.entity.Player getPlayer() {
        return org.bukkit.Bukkit.getPlayer(playerUuid);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        GuildMember that = (GuildMember) o;
        return Objects.equals(playerUuid, that.playerUuid);
    }

    @Override
    public int hashCode() {
        return Objects.hash(playerUuid);
    }
}
