package ru.yandex.canvas.model.html5;

import java.time.LocalDateTime;
import java.util.List;

import javax.validation.constraints.NotNull;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.CompoundIndexes;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import ru.yandex.canvas.repository.mongo.MongoField;
import ru.yandex.canvas.service.SessionParams;

import static java.util.Collections.emptyList;
import static ru.yandex.canvas.repository.mongo.MongoField.ofFieldPath;
import static ru.yandex.direct.utils.CommonUtils.nvl;

/**
 * > db.html5_batches.find().limit(1).pretty()
 * {
 * "_id" : ObjectId("5a26a1d9314d9c0015de2137"),
 * "id" : null,
 * "client_id" : 16948833,
 * "date" : ISODate("2017-12-05T16:40:41.700Z"),
 * "archive" : false,
 * "name" : "Новый креатив",
 */

@Document(collection = "html5_batches")

@CompoundIndexes({
        @CompoundIndex(def = "{'client_id': 1, 'archive': 1, 'date': -1}"),
})

public class Batch {


    public static final String ID_FIELD_NAME = "_id";
    public static final String NAME_FIELD_NAME = "name";
    public static final String CLIENT_ID_FIELD_NAME = "client_id";
    public static final String ARCHIVE_FIELD_NAME = "archive";
    public static final String CREATIVES_FIELD_NAME = "creatives";
    public static final String DATE_FIELD_NAME = "date";
    public static final String PRODUCT_TYPE_FIELD_NAME = "product_type";
    public static final String FOUND_ITEM = "$"; // $ - индекс элемента массива, который был найден в where

    public static final MongoField CLIENT_ID = ofFieldPath(CLIENT_ID_FIELD_NAME);
    public static final MongoField ARCHIVE = ofFieldPath(ARCHIVE_FIELD_NAME);
    public static final MongoField ID = ofFieldPath(ID_FIELD_NAME);
    public static final MongoField CREATIVE_ID = ofFieldPath(CREATIVES_FIELD_NAME, Creative.ID_FIELD_NAME);
    public static final MongoField CREATIVE_WIDTH = ofFieldPath(CREATIVES_FIELD_NAME, Creative.WIDTH_FIELD_NAME);
    public static final MongoField CREATIVE_HEIGHT = ofFieldPath(CREATIVES_FIELD_NAME, Creative.HEIGHT_FIELD_NAME);
    public static final MongoField CREATIVE_SCREENSHOT = ofFieldPath(CREATIVES_FIELD_NAME,
            Creative.SCREENSHOT_URL_FIELD_NAME);
    public static final MongoField CREATIVE_SOURCE_ID = ofFieldPath(CREATIVES_FIELD_NAME,
            Creative.SOURCE_FIELD_NAME, Source.ID_FIELD_NAME);
    public static final MongoField CREATIVE_SOURCE_HTML_REPLACEMENTS = ofFieldPath(CREATIVES_FIELD_NAME,
            Creative.SOURCE_FIELD_NAME, Source.HTML_REPLACEMENTS_NAME);
    public static final MongoField CREATIVE_SOURCE_DATE = ofFieldPath(CREATIVES_FIELD_NAME,
        Creative.SOURCE_FIELD_NAME, Source.DATE_FIELD_NAME);

    public static final MongoField FOUND_CREATIVE = ofFieldPath(CREATIVES_FIELD_NAME, FOUND_ITEM);
    public static final MongoField FOUND_CREATIVE_SOURCE = ofFieldPath(CREATIVES_FIELD_NAME, FOUND_ITEM,
            Creative.SOURCE_FIELD_NAME);
    public static final MongoField FOUND_CREATIVE_SOURCE_HTML_REPLACEMENTS = ofFieldPath(CREATIVES_FIELD_NAME, FOUND_ITEM,
            Creative.SOURCE_FIELD_NAME, Source.HTML_REPLACEMENTS_NAME);
    public static final MongoField FOUND_EXPANDED = ofFieldPath(CREATIVES_FIELD_NAME,
            Creative.SOURCE_FIELD_NAME, Source.EXPANDED_HTML_URL_NAME);
    public static final MongoField FOUND_CREATIVE_SCREENSHOT = ofFieldPath(CREATIVES_FIELD_NAME, FOUND_ITEM,
            Creative.SCREENSHOT_URL_FIELD_NAME);

    public static final MongoField CREATIVE_ADMIN_REJECT_REASON = ofFieldPath(CREATIVES_FIELD_NAME,
            Creative.ADMIN_REJECT_REASON);

    public static final MongoField PRODUCT_TYPE = ofFieldPath(PRODUCT_TYPE_FIELD_NAME);
    public static final MongoField NAME = ofFieldPath(NAME_FIELD_NAME);
    public static final MongoField DATE = ofFieldPath(DATE_FIELD_NAME);

    @Id
    private String id;

    @NotNull
    private String name;

    /**
     * Тип продукта, если тут null - то это на самом деле CPM_BANNER
     */
    @Field("product_type")
    @JsonProperty("product_type")
    private SessionParams.SessionTag productType;

    @NotNull
    @Field(CLIENT_ID_FIELD_NAME)
    @JsonProperty(CLIENT_ID_FIELD_NAME)
    private Long clientId;

    private Boolean archive;

    private LocalDateTime date;

    @Transient
    @JsonSerialize
    @JsonProperty("available")
    private Boolean available;

    private List<Creative> creatives;

    public String getId() {
        return id;
    }

    public Batch setId(String id) {
        this.id = id;
        return this;
    }

    public String getName() {
        return name;
    }

    public Batch setName(String name) {
        this.name = name;
        return this;
    }

    public SessionParams.SessionTag getProductType() {
        return productType;
    }

    public Batch setProductType(SessionParams.SessionTag productType) {
        this.productType = productType;
        return this;
    }

    public Long getClientId() {
        return clientId;
    }

    public Batch setClientId(Long clientId) {
        this.clientId = clientId;
        return this;
    }

    public Boolean getArchive() {
        return archive;
    }

    public Batch setArchive(Boolean archive) {
        this.archive = archive;
        return this;
    }

    public LocalDateTime getDate() {
        return date;
    }

    public Batch setDate(LocalDateTime date) {
        this.date = date;
        return this;
    }

    public Boolean getAvailable() {
        return available;
    }

    public Batch setAvailable(Boolean available) {
        this.available = available;
        return this;
    }

    public List<Creative> getCreatives() {
        return nvl(creatives, emptyList());
    }

    public Batch setCreatives(List<Creative> creatives) {
        this.creatives = creatives;
        return this;
    }
}
