package io.delphiplatform.api.v3.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import org.openapitools.jackson.nullable.JsonNullable;
import org.springframework.format.annotation.DateTimeFormat;

import java.time.LocalDate;
import java.util.Objects;
import java.util.Set;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;

import io.delphiplatform.api.v3.constant.ApplicationConstants;
import io.delphiplatform.api.v3.model.gras.Company;
import io.delphiplatform.api.v3.rdb.entity.TrackEntity;

/**
 * TrackSimple
 */
@JsonPropertyOrder(alphabetic = true)
public class TrackSimple {

    @JsonProperty("isrc")
    private String isrc;

    @JsonProperty("lyrics_version")
    private String lyricsVersion;

    @JsonProperty("name")
    private String name;

    @JsonProperty("product")
    private ProductSimple product;

    @JsonProperty("release_date")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
    private LocalDate releaseDate;

    @JsonProperty("track_id")
    private String trackId;

    @JsonProperty("track_name_suppl")
    private String trackNameSuppl;

    @JsonProperty("rep_owner_key")
    private String repOwnerKey;

    @JsonProperty("rep_owner_company")
    private Company repOwnerCompany;

    @JsonProperty("track_type_name")
    private String trackTypeName;

    @JsonProperty("related_isrcs")
    private JsonNullable<Set<String>> relatedIsrcs = JsonNullable.undefined();

    public static TrackSimple from(TrackEntity track) {
        if (track == null) {
            return null;
        }
        return new TrackSimple()
            .name(track.getName())
            .trackNameSuppl(track.getTrackNameSuppl())
            .trackId(track.getTrackId())
            .product(ProductSimple.from(track.getProduct()))
            .isrc(track.getIsrc())
            .lyricsVersion(track.getLyricsVersion())
            .repOwnerKey(track.getRepertoireOwner() == null ? null : track.getRepertoireOwner().getRepOwnerKey())
            .repOwnerCompany(track.getRepertoireOwner() == null
                ? null
                : Company.from(track.getRepertoireOwner().getRepertoireOwnerCompany()))
            .trackTypeName(track.getTrackTypeName())
            .releaseDate(track.getReleaseDate());
    }

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

    @NotNull
    public String getName() {
        return name;
    }

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

    public JsonNullable<Set<String>> getRelatedIsrcs() {
        return relatedIsrcs;
    }

    public void setRelatedIsrcs(JsonNullable<Set<String>> relatedIsrcs) {
        this.relatedIsrcs = relatedIsrcs;
    }

    public TrackSimple lyricsVersion(String lyricsVersion) {
        this.lyricsVersion = lyricsVersion;
        return this;
    }

    @NotNull
    public String getLyricsVersion() {
        return lyricsVersion;
    }

    public void setLyricsVersion(String lyricsVersion) {
        this.lyricsVersion = lyricsVersion;
    }

    public TrackSimple trackNameSuppl(String trackNameSuppl) {
        this.trackNameSuppl = trackNameSuppl;
        return this;
    }

    public String getTrackNameSuppl() {
        return trackNameSuppl;
    }

    public void setTrackNameSuppl(String trackNameSuppl) {
        this.trackNameSuppl = trackNameSuppl;
    }

    public TrackSimple trackId(String trackId) {
        this.trackId = trackId;
        return this;
    }

    @NotNull
    public String getTrackId() {
        return trackId;
    }

    public void setTrackId(String trackId) {
        this.trackId = trackId;
    }

    public TrackSimple product(ProductSimple product) {
        this.product = product;
        return this;
    }

    @Valid
    public ProductSimple getProduct() {
        return product;
    }

    public void setProduct(ProductSimple product) {
        this.product = product;
    }

    public TrackSimple isrc(String isrc) {
        this.isrc = isrc;
        return this;
    }

    @NotNull
    @Pattern(regexp = ApplicationConstants.ISRC_PATTERN)
    public String getIsrc() {
        return isrc;
    }

    public void setIsrc(String isrc) {
        this.isrc = isrc;
    }

    public TrackSimple releaseDate(LocalDate releaseDate) {
        this.releaseDate = releaseDate;
        return this;
    }

    @Valid
    public LocalDate getReleaseDate() {
        return releaseDate;
    }

    public void setReleaseDate(LocalDate releaseDate) {
        this.releaseDate = releaseDate;
    }

    public TrackSimple repOwnerKey(String repOwnerKey) {
        this.repOwnerKey = repOwnerKey;
        return this;
    }

    /**
     * Primary key identifier for a Company, also used via RepertoireOwner, ParentRepertoireOwner and ProfitCenter.
     *
     * @return repOwnerKey
     */
    public String getRepOwnerKey() {
        return repOwnerKey;
    }

    public void setRepOwnerKey(String repOwnerKey) {
        this.repOwnerKey = repOwnerKey;
    }

    public TrackSimple repOwnerCompany(Company repOwnerCompany) {
        this.repOwnerCompany = repOwnerCompany;
        return this;
    }

    public Company getRepOwnerCompany() {
        return repOwnerCompany;
    }

    public void setRepOwnerCompany(Company repOwnerCompany) {
        this.repOwnerCompany = repOwnerCompany;
    }

    public TrackSimple trackTypeName(String trackTypeName) {
        this.trackTypeName = trackTypeName;
        return this;
    }

    /**
     * Track type name of the Track.
     *
     * @return trackTypeName
     */
    public String getTrackTypeName() {
        return trackTypeName;
    }

    public void setTrackTypeName(String trackTypeName) {
        this.trackTypeName = trackTypeName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        TrackSimple trackSimple = (TrackSimple) o;
        return Objects.equals(this.name, trackSimple.name) &&
            Objects.equals(this.trackNameSuppl, trackSimple.trackNameSuppl) &&
            Objects.equals(this.trackId, trackSimple.trackId) &&
            Objects.equals(this.product, trackSimple.product) &&
            Objects.equals(this.repOwnerCompany, trackSimple.repOwnerCompany) &&
            Objects.equals(this.isrc, trackSimple.isrc) &&
            Objects.equals(this.releaseDate, trackSimple.releaseDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, trackNameSuppl, trackId, product, isrc, releaseDate);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("class TrackSimple {\n");

        sb.append("    name: ").append(toIndentedString(name)).append("\n");
        sb.append("    trackNameSuppl: ").append(toIndentedString(trackNameSuppl)).append("\n");
        sb.append("    trackId: ").append(toIndentedString(trackId)).append("\n");
        sb.append("    product: ").append(toIndentedString(product)).append("\n");
        sb.append("    repOwnerCompany: ").append(toIndentedString(repOwnerCompany)).append("\n");
        sb.append("    isrc: ").append(toIndentedString(isrc)).append("\n");
        sb.append("    releaseDate: ").append(toIndentedString(releaseDate)).append("\n");
        sb.append("}");
        return sb.toString();
    }

    /**
     * Convert the given object to string with each line indented by 4 spaces (except the first line).
     */
    private String toIndentedString(Object o) {
        if (o == null) {
            return "null";
        }
        return o.toString().replace("\n", "\n    ");
    }
}
