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

import java.util.List;

import javax.annotation.ParametersAreNonnullByDefault;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * PreOrder is presentation of {@link ru.yandex.qe.dispenser.domain.dao.bot.MappedPreOrder} which we sync to the BOT
 *
 * @see ru.yandex.qe.dispenser.domain.dao.bot.MappedPreOrder
 */
@ParametersAreNonnullByDefault
public class PreOrder {
    private final long id;
    @NotNull
    private final Version currentVersion;

    @JsonCreator
    public PreOrder(@JsonProperty("id") final long id,
                    @JsonProperty("current_version") final Version currentVersion) {
        this.id = id;
        this.currentVersion = currentVersion;
    }

    public long getId() {
        return id;
    }

    public Version getCurrentVersion() {
        return currentVersion;
    }

    public enum Status {
        DRAFTED(1),
        COMMITED(2),
        APPROVED(3);

        private final int code;

        Status(final int code) {
            this.code = code;
        }

        public int getCode() {
            return code;
        }

        public static Status fromCode(final int code) {
            for (final Status value : values()) {
                if (value.getCode() == code) {
                    return value;
                }
            }
            return null;
        }
    }

    public static class Version {
        private final long id;
        private final int statusId;
        private final BigOrderConfig bigOrderConfig;
        @Nullable
        private final Server server;
        @Nullable
        private final Long serverQuantity;
        @Nullable
        private final Server storage;
        @Nullable
        private final Long storageQuantity;
        private final OebsService oebsService;
        @Nullable
        private final String ticketId;
        @Nullable
        private final String customerComment;
        private final String responsible;
        @Nullable
        private final List<Components> components;
        private final boolean isDeleted;

        @JsonCreator
        public Version(@JsonProperty("id") final long id,
                       @JsonProperty("status_id") final Integer statusId,
                       @JsonProperty("big_order_config") final BigOrderConfig bigOrderConfig,
                       @Nullable @JsonProperty("server") final Server server,
                       @Nullable @JsonProperty("servers_quantity") final Long serverQuantity,
                       @Nullable @JsonProperty("storage") final Server storage,
                       @Nullable @JsonProperty("storages_quantity") final Long storageQuantity,
                       @JsonProperty("oebs_service") final OebsService oebsService,
                       @Nullable @JsonProperty("ticket_id") final String ticketId,
                       @Nullable @JsonProperty("customer_comment") final String customerComment,
                       @JsonProperty("responsible") final String responsible,
                       @Nullable @JsonProperty("components") final List<Components> components,
                       @JsonProperty("is_deleted") boolean isDeleted) {
            this.id = id;
            this.statusId = statusId;
            this.bigOrderConfig = bigOrderConfig;
            this.server = server;
            this.serverQuantity = serverQuantity;
            this.storage = storage;
            this.storageQuantity = storageQuantity;
            this.oebsService = oebsService;
            this.ticketId = ticketId;
            this.customerComment = customerComment;
            this.responsible = responsible;
            this.components = components;
            this.isDeleted = isDeleted;
        }

        public long getId() {
            return id;
        }

        public int getStatusId() {
            return statusId;
        }

        public BigOrderConfig getBigOrderConfig() {
            return bigOrderConfig;
        }

        @Nullable
        public Server getServer() {
            return server;
        }

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

        @Nullable
        public Server getStorage() {
            return storage;
        }

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

        public OebsService getOebsService() {
            return oebsService;
        }

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

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

        public String getResponsible() {
            return responsible;
        }

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

        public boolean isDeleted() {
            return isDeleted;
        }
    }

    public static class BigOrderConfig {
        private final long id;
        private final BigOrder bigOrder;
        private final String categoryCode;

        @JsonCreator
        public BigOrderConfig(@JsonProperty("id") final long id,
                              @JsonProperty("big_order") final BigOrder bigOrder,
                              @JsonProperty("category_code") final String categoryCode) {
            this.id = id;
            this.bigOrder = bigOrder;
            this.categoryCode = categoryCode;
        }

        public long getId() {
            return id;
        }

        @JsonProperty("big_order")
        public BigOrder getBigOrder() {
            return bigOrder;
        }

        @JsonProperty("category_code")
        public String getCategoryCode() {
            return categoryCode;
        }
    }

    public static class BigOrder {
        private final long id;

        @JsonCreator
        public BigOrder(@JsonProperty("id") final long id) {
            this.id = id;
        }

        public long getId() {
            return id;
        }
    }

    public static class Server {
        private final long id;

        @JsonCreator
        public Server(@JsonProperty("id") final long id) {
            this.id = id;
        }

        public long getId() {
            return id;
        }
    }

    public static class OebsService {
        private final long id;

        @JsonCreator
        public OebsService(@JsonProperty("id") final long id) {
            this.id = id;
        }

        public long getId() {
            return id;
        }
    }
        public static class Components {
        private final long quantity;
        private final Component component;

        @JsonCreator
        public Components(@JsonProperty("quantity") final long quantity,
                          @JsonProperty("component") final Component component) {
            this.quantity = quantity;
            this.component = component;
        }

        public long getQuantity() {
            return quantity;
        }

        public Component getComponent() {
            return component;
        }
    }

    public static class Component extends BaseConfigurationEntity {

        private final String id;

        public Component(@JsonProperty("id") final String id,
                         @JsonProperty("full_name") final String fullName,
                         @JsonProperty("type_id") final Long typeId, @JsonProperty("type_code") final String typeCode,
                         @JsonProperty("type_display") final String typeDisplay,
                         @JsonProperty("enabled") final boolean enabled,
                         @JsonProperty("recommended") final boolean recommended,
                         @Nullable @JsonProperty("description") final String description) {
            super(fullName, typeId, typeCode, typeDisplay, enabled, recommended, description);
            this.id = id;
        }

        public String getId() {
            return id;
        }
    }
}
