package com.bitnix.dirtcryptostore.model;

import java.util.UUID;

public class PendingInvoice {

    public enum Status {
        PENDING,
        DETECTED,
        FULFILLED,
        EXPIRED,
        CANCELLED,
        UNDER_REVIEW
    }

    private final String invoiceId;
    private final UUID playerUuid;
    private final String playerName;
    private final String productId;
    private final String walletId;
    private final String walletAddress;
    private final long amountSats;
    private final long createdAt;
    private final long expiresAt;

    private Status status;
    private String txid;
    private int confirmations;
    private boolean fulfilled;
    private long matchedAt;
    private long fulfilledAt;
    private String notes;

    public PendingInvoice(String invoiceId,
                          UUID playerUuid,
                          String playerName,
                          String productId,
                          String walletId,
                          String walletAddress,
                          long amountSats,
                          long createdAt,
                          long expiresAt,
                          Status status,
                          String txid,
                          int confirmations,
                          boolean fulfilled,
                          long matchedAt,
                          long fulfilledAt,
                          String notes) {
        this.invoiceId = invoiceId;
        this.playerUuid = playerUuid;
        this.playerName = playerName;
        this.productId = productId;
        this.walletId = walletId;
        this.walletAddress = walletAddress;
        this.amountSats = amountSats;
        this.createdAt = createdAt;
        this.expiresAt = expiresAt;
        this.status = status == null ? Status.PENDING : status;
        this.txid = txid == null ? "" : txid;
        this.confirmations = confirmations;
        this.fulfilled = fulfilled;
        this.matchedAt = matchedAt;
        this.fulfilledAt = fulfilledAt;
        this.notes = notes == null ? "" : notes;
    }

    public String getInvoiceId() {
        return invoiceId;
    }

    public UUID getPlayerUuid() {
        return playerUuid;
    }

    public String getPlayerName() {
        return playerName;
    }

    public String getProductId() {
        return productId;
    }

    public String getWalletId() {
        return walletId;
    }

    public String getWalletAddress() {
        return walletAddress;
    }

    public long getAmountSats() {
        return amountSats;
    }

    public long getCreatedAt() {
        return createdAt;
    }

    public long getExpiresAt() {
        return expiresAt;
    }

    public Status getStatus() {
        return status;
    }

    public String getTxid() {
        return txid;
    }

    public int getConfirmations() {
        return confirmations;
    }

    public boolean isFulfilled() {
        return fulfilled;
    }

    public long getMatchedAt() {
        return matchedAt;
    }

    public long getFulfilledAt() {
        return fulfilledAt;
    }

    public String getNotes() {
        return notes;
    }

    public void setStatus(Status status) {
        this.status = status == null ? Status.PENDING : status;
    }

    public void setTxid(String txid) {
        this.txid = txid == null ? "" : txid;
    }

    public void setConfirmations(int confirmations) {
        this.confirmations = confirmations;
    }

    public void setFulfilled(boolean fulfilled) {
        this.fulfilled = fulfilled;
    }

    public void setMatchedAt(long matchedAt) {
        this.matchedAt = matchedAt;
    }

    public void setFulfilledAt(long fulfilledAt) {
        this.fulfilledAt = fulfilledAt;
    }

    public void setNotes(String notes) {
        this.notes = notes == null ? "" : notes;
    }

    public boolean isExpired() {
        return System.currentTimeMillis() > expiresAt;
    }

    public long getRemainingMillis() {
        return Math.max(0L, expiresAt - System.currentTimeMillis());
    }

    public boolean isFinalState() {
        return status == Status.FULFILLED
                || status == Status.EXPIRED
                || status == Status.CANCELLED;
    }

    public boolean isMatchable() {
        return status == Status.PENDING || status == Status.DETECTED;
    }
}
