package ru.yandex.qe.dispenser.domain.dao.bot;

import java.util.List;

import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.ParametersAreNullableByDefault;

import ru.yandex.qe.dispenser.domain.bot.PreOrder;
import ru.yandex.qe.dispenser.domain.index.LongIndexBase;

import static java.util.Objects.requireNonNull;

@ParametersAreNonnullByDefault
public class BotPreOrder extends LongIndexBase implements PreOrderBase{
    private final int statusId;
    private final long bigOrderId;
    private final long bigOrderConfigId;
    private final String categoryCode;
    @Nullable
    private final Long server;
    @Nullable
    private final Long serverQuantity;
    @Nullable
    private final Long storage;
    @Nullable
    private final Long storageQuantity;
    private final Long oebsServiceId;
    @Nullable
    private final String ticketId;
    @Nullable
    private final String customerComment;
    private final String responsible;
    private final boolean deleted;

    @Nullable
    private final List<PreOrder.Components> components;
    @Nullable
    private final Integer abcServiceId;
    private final long upgradesCost;

    private BotPreOrder(final Builder builder) {
        this.statusId = requireNonNull(builder.statusId, "status must be defined");
        this.bigOrderId = requireNonNull(builder.bigOrderId, "bigOrderId must be defined");
        this.bigOrderConfigId = requireNonNull(builder.bigOrderConfigId, "bigOrderConfigId must be defined");
        this.categoryCode = requireNonNull(builder.categoryCode, "categoryCode must be defined");
        this.server = builder.server;
        this.serverQuantity = builder.serverQuantity;
        this.storage = builder.storage;
        this.storageQuantity = builder.storageQuantity;
        this.oebsServiceId = requireNonNull(builder.oebsServiceId, "oebsServiceId must be defined");
        this.ticketId = builder.ticketId;
        this.customerComment = builder.customerComment;
        this.responsible = requireNonNull(builder.responsible, "responsible must be defined");
        this.components = builder.components;
        this.deleted = requireNonNull(builder.deleted, "deleted must be defined");
        this.abcServiceId = builder.abcServiceId;
        this.upgradesCost = requireNonNull(builder.upgradesCost, "upgradesCost must be defined");
        if (builder.id != null) {
            setId(builder.id);
        }
    }

    public int getStatusId() {
        return statusId;
    }

    public long getBigOrderId() {
        return bigOrderId;
    }

    public long getBigOrderConfigId() {
        return bigOrderConfigId;
    }

    public String getCategoryCode() {
        return categoryCode;
    }

    @Override
    @Nullable
    public Long getServerId() {
        return server;
    }

    @Override
    @Nullable
    public Long getServerQuantity() {
        return serverQuantity;
    }

    @Override
    @Nullable
    public Long getStorageId() {
        return storage;
    }

    @Override
    @Nullable
    public Long getStorageQuantity() {
        return storageQuantity;
    }

    public Long getOebsServiceId() {
        return oebsServiceId;
    }

    @Nullable
    public String getTicketId() {
        return ticketId;
    }

    @Nullable
    public String getCustomerComment() {
        return customerComment;
    }

    public String getResponsible() {
        return responsible;
    }

    @Nullable
    public List<PreOrder.Components> getComponents() {
        return components;
    }

    public boolean isDeleted() {
        return deleted;
    }

    @Nullable
    public Integer getAbcServiceId() {
        return abcServiceId;
    }

    public long getUpgradesCost() {
        return upgradesCost;
    }

    public BotPreOrder withDeletedInBot(final boolean deleted) {
        return copyBuilder()
                .deleted(deleted)
                .build();
    }

    public Builder copyBuilder() {
        final Builder builder = new Builder()
                .id(getId())
                .statusId(statusId)
                .bigOrderId(bigOrderId)
                .bigOrderConfigId(bigOrderConfigId)
                .categoryCode(categoryCode)
                .server(server)
                .serverQuantity(serverQuantity)
                .storage(storage)
                .storageQuantity(storageQuantity)
                .oebsServiceId(oebsServiceId)
                .ticketId(ticketId)
                .customerComment(customerComment)
                .responsible(responsible)
                .components(this.components)
                .deleted(this.deleted)
                .abcServiceId(this.abcServiceId)
                .upgradesCost(this.upgradesCost);

        if (getId() >= 0) {
            builder.id(getId());
        }

        return builder;
    }

    @ParametersAreNullableByDefault
    public static class Builder {
        private Long id;
        private Integer statusId;
        private Long bigOrderId;
        private Long bigOrderConfigId;
        private String categoryCode;
        private Long server;
        private Long serverQuantity;
        private Long storage;
        private Long storageQuantity;
        private Long oebsServiceId;
        private String ticketId;
        private String customerComment;
        private String responsible;
        private List<PreOrder.Components> components;
        private Boolean deleted;
        private Integer abcServiceId;
        private Long upgradesCost;

        public Builder id(final Long id) {
            this.id = id;
            return this;
        }

        public Builder statusId(final int statusId) {
            this.statusId = statusId;
            return this;
        }

        public Builder bigOrderId(final Long bigOrderId) {
            this.bigOrderId = bigOrderId;
            return this;
        }

        public Builder bigOrderConfigId(final Long bigOrderConfigId) {
            this.bigOrderConfigId = bigOrderConfigId;
            return this;
        }

        public Builder categoryCode(final String categoryCode) {
            this.categoryCode = categoryCode;
            return this;
        }

        public Builder server(final Long server) {
            this.server = server;
            return this;
        }

        public Builder serverQuantity(final Long serverQuantity) {
            this.serverQuantity = serverQuantity;
            return this;
        }

        public Builder storage(final Long storage) {
            this.storage = storage;
            return this;
        }

        public Builder storageQuantity(final Long storageQuantity) {
            this.storageQuantity = storageQuantity;
            return this;
        }

        public Builder oebsServiceId(final Long oebsServiceId) {
            this.oebsServiceId = oebsServiceId;
            return this;
        }

        public Builder ticketId(final String ticketId) {
            this.ticketId = ticketId;
            return this;
        }

        public Builder customerComment(final String customerComment) {
            this.customerComment = customerComment;
            return this;
        }

        public Builder responsible(final String responsible) {
            this.responsible = responsible;
            return this;
        }

        public Builder components(final List<PreOrder.Components> components) {
            this.components = components;
            return this;
        }

        public Builder deleted(final boolean deleted) {
            this.deleted = deleted;
            return this;
        }
        public Builder upgradesCost(final long upgradesCost) {
            this.upgradesCost = upgradesCost;
            return this;
        }

        public Builder abcServiceId(final Integer abcServiceId) {
            this.abcServiceId = abcServiceId;
            return this;
        }

        public BotPreOrder build() {
            return new BotPreOrder(this);
        }

    }
}
