package inn.ocsf.bee.freigeld.core.model.data;

import com.fasterxml.jackson.annotation.JsonIgnore;
import inn.ocsf.bee.freigeld.core.model.BankAccount;
import inn.ocsf.bee.freigeld.core.model.Coin;
import org.bson.types.ObjectId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.annotation.Version;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Collection;
import java.util.UUID;

@Document("account")
public class BankAccountData {

    @Id
    private ObjectId id;

    @Version
    private Long version;

    private BankAccount account;

    private UUID bankId;

    public UUID getBankId() {
        return bankId;
    }

    public void setBankId(UUID bankId) {
        this.bankId = bankId;
    }

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public BankAccount getAccount() {
        return account;
    }

    public void setAccount(BankAccount account) {
        this.account = account;
    }

    public static class BankAccountDefault implements BankAccount {

        private UUID id;
        private UUID ownerId;
        private Long overall;
        @Transient
        @JsonIgnore
        private BankAccount transientDelegate;

        public BankAccountDefault(UUID id, UUID ownerId) {
            this.id = id;
            this.ownerId = ownerId;
            this.overall = 0L;
        }

        public BankAccountDefault() {
        }

        @Override
        public UUID getId() {
            return id;
        }

        public void setId(UUID id) {
            this.id = id;
        }

        @Override
        public UUID getOwnerId() {
            return ownerId;
        }

        public void setOwnerId(UUID ownerId) {
            this.ownerId = ownerId;
        }

        public BankAccount getTransientDelegate() {
            return transientDelegate;
        }

        public void setTransientDelegate(BankAccount transientDelegate) {
            this.transientDelegate = transientDelegate;
        }

        @Override
        public Long getOverall() {
            this.overall = transientDelegate.getOverall();
            return this.overall;
        }

        public void setOverall(Long overall) {
            this.overall = overall;
        }

        @Nullable
        @Override
        public Collection<Coin> getCoins() {
            return transientDelegate.getCoins();
        }

        @Nullable
        @Override
        public Coin extractOne(@NotNull UUID coinId) {
            return transientDelegate.extractOne(coinId);
        }

        @Override
        public void acceptOne(@NotNull Coin coin) {
            transientDelegate.acceptOne(coin);
        }

        @Override
        public String toString() {
            return id.toString();
        }
    }
}
