package io.delphiplatform.api.v3.model;

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

import org.springframework.format.annotation.DateTimeFormat;

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

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

/**
 * Schema containing the Spotify popularity fields
 */
@JsonPropertyOrder(alphabetic = true)
public class Popularity {

    @JsonProperty("artist_id")
    private String artistId;

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

    @JsonProperty("spotify_popularity")
    private Long spotifyPopularity;

    public Popularity artistId(String artistId) {
        this.artistId = artistId;
        return this;
    }

    /**
     * Primary key identifier for Artist
     *
     * @return artistId
     */
    public String getArtistId() {
        return artistId;
    }

    public void setArtistId(String artistId) {
        this.artistId = artistId;
    }

    public Popularity date(LocalDate date) {
        this.date = date;
        return this;
    }

    /**
     * ISO 8601 date in format `YYYY-MM-DD`
     *
     * @return date
     */
    @Valid
    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$")
    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public Popularity spotifyPopularity(Long spotifyPopularity) {
        this.spotifyPopularity = spotifyPopularity;
        return this;
    }

    /**
     * The popularity of a track is a value between 0 and 100, with 100 being the most popular. The popularity is
     * calculated by algorithm and is based, in the most part, on the total number of plays the track has had and how
     * recent those plays are. Generally speaking, songs that are being played a lot now will have a higher popularity
     * than songs that were played a lot in the past. Duplicate tracks (e.g. the same track from a single and an
     * product) are rated independently. Artist and album popularity is derived mathematically from track popularity.
     * Note that the popularity value may lag actual popularity by a few days: the value is not updated in real time.
     *
     * @return spotifyPopularity
     */
    @NotNull
    public Long getSpotifyPopularity() {
        return spotifyPopularity;
    }

    public void setSpotifyPopularity(Long spotifyPopularity) {
        this.spotifyPopularity = spotifyPopularity;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Popularity popularity = (Popularity) o;
        return Objects.equals(this.artistId, popularity.artistId) &&
            Objects.equals(this.date, popularity.date) &&
            Objects.equals(this.spotifyPopularity, popularity.spotifyPopularity);
    }

    @Override
    public int hashCode() {
        return Objects.hash(artistId, date, spotifyPopularity);
    }

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

        sb.append("    artistId: ").append(toIndentedString(artistId)).append("\n");
        sb.append("    date: ").append(toIndentedString(date)).append("\n");
        sb.append("    spotifyPopularity: ").append(toIndentedString(spotifyPopularity)).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    ");
    }
}
