package eu.eudat.data.entities;

import eu.eudat.data.converters.DateToUTCConverter;
import eu.eudat.data.entities.helpers.EntityBinder;
import eu.eudat.queryable.queryableentity.DataEntity;
import org.hibernate.annotations.Type;

import javax.persistence.*;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Entity
@Table(name = "\"EntityDoi\"")
public class EntityDoi implements DataEntity<EntityDoi, UUID> {
    public enum EntityType {
        DMP
    }

    @Id
    @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)")
    private UUID id;

    @Enumerated(EnumType.STRING)
    @Type(type = "eu.eudat.configurations.typedefinition.PostgreSQLEnumType")
    @Column(name = "\"EntityType\"", nullable = false)
    private EntityType entityType;

    @Column(name = "\"RepositoryId\"", nullable = false)
    private String repositoryId;

    @Column(name = "\"Doi\"", nullable = false)
    private String doi;

    @Column(name = "\"CreatedAt\"", nullable = false)
    @Convert(converter = DateToUTCConverter.class)
    private Date createdAt;

    @Column(name = "\"UpdatedAt\"", nullable = false)
    @Convert(converter = DateToUTCConverter.class)
    private Date updatedAt;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "\"EntityId\"", nullable = false)
    private DMP entityId;

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

    public EntityType getEntityType() {
        return entityType;
    }
    public void setEntityType(EntityType entityType) {
        this.entityType = entityType;
    }

    public String getRepositoryId() {
        return repositoryId;
    }
    public void setRepositoryId(String repositoryId) {
        this.repositoryId = repositoryId;
    }

    public String getDoi() {
        return doi;
    }
    public void setDoi(String doi) {
        this.doi = doi;
    }

    public Date getCreatedAt() {
        return createdAt;
    }
    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }
    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public DMP getEntityId() {
        return entityId;
    }
    public void setEntityId(DMP entityId) {
        this.entityId = entityId;
    }

    @Override
    public void update(EntityDoi doi) {
        this.entityType = doi.getEntityType();
        this.repositoryId = doi.getRepositoryId();
        this.doi = doi.getDoi();
        this.createdAt = doi.getCreatedAt();
        this.updatedAt = doi.getUpdatedAt();
        this.entityId = doi.getEntityId();
    }

    @Override
    public UUID getKeys() {
        return this.id;
    }

    @Override
    public EntityDoi buildFromTuple(List<Tuple> tuple, List<String> fields, String base) {
        String currentBase = base.isEmpty() ? "" : base + ".";
        if (fields.contains(currentBase + "id")) this.id = EntityBinder.fromTuple(tuple, currentBase + "id");
        if (fields.contains(currentBase + "entityId"))
            this.entityId = tuple.stream().map(x -> new DMP().buildFromTuple(Arrays.asList(x), fields , base.isEmpty() ? "entityId" : base + "." + "entityId")).collect(Collectors.toList()).get(0);
        return this;
    }
}
