package io.delphiplatform.api.v3.model.video;

import com.fasterxml.jackson.annotation.JsonProperty;

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

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

import io.delphiplatform.api.v3.rdb.entity.video.FactYoutubeVideoTrendingChartEntity;

/**
 * ChartPosition
 */
public class ChartPosition {

    @JsonProperty("current")
    private Integer current;

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

    @JsonProperty("date_gap")
    private JsonNullable<Integer> dateGap = JsonNullable.undefined();

    @JsonProperty("is_entry")
    private Boolean isEntry = false;

    @JsonProperty("is_exit")
    private Boolean isExit;

    @JsonProperty("is_reentry")
    private Boolean isReentry = false;

    @JsonProperty("previous_date")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
    private JsonNullable<LocalDate> previousDate = JsonNullable.undefined();

    @JsonProperty("previous_position")
    private Integer previousPosition;

    @JsonProperty("trend")
    private Integer trend;

    public static ChartPosition of(FactYoutubeVideoTrendingChartEntity entity) {
        if (entity == null) {
            return null;
        }
        return new ChartPosition()
            .current(entity.getCurrentPosition())
            .date(entity.getDate())
            .dateGap(entity.getDateGap())
            .isEntry(entity.getIsEntry())
            .isReentry(entity.getIsReentry())
            .isExit(entity.getIsExit())
            .previousDate(entity.getPreviousDate())
            .previousPosition(entity.getPreviousPosition())
            .trend(entity.getTrend());
    }

    public ChartPosition current(Integer current) {
        this.current = current;
        return this;
    }

    /**
     * The entity's position (or \"rank\") on the current `date`.
     *
     * @return current
     */
    public Integer getCurrent() {
        return current;
    }

    public void setCurrent(Integer current) {
        this.current = current;
    }

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

    /**
     * [ISO 8601 date](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates) in format `YYYY-MM-DD`
     *
     * @return date
     */
    public LocalDate getDate() {
        return date;
    }

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

    public ChartPosition dateGap(Integer dateGap) {
        this.dateGap = JsonNullable.of(dateGap);
        return this;
    }

    /**
     * Difference in days between the current position `date` and `previous_date`.
     *
     * @return dateGap
     */
    public JsonNullable<Integer> getDateGap() {
        return dateGap;
    }

    public void setDateGap(JsonNullable<Integer> dateGap) {
        this.dateGap = dateGap;
    }

    public ChartPosition isEntry(Boolean isEntry) {
        this.isEntry = isEntry;
        return this;
    }

    /**
     * True if this entity was not on the chart the day before (`date - 1 day`).
     *
     * @return isEntry
     */
    public Boolean getIsEntry() {
        return isEntry;
    }

    public void setIsEntry(Boolean isEntry) {
        this.isEntry = isEntry;
    }

    public ChartPosition isExit(Boolean isExit) {
        this.isExit = isExit;
        return this;
    }

    /**
     * True if the entity appeared on the Chart or Playlist on the `previous_date` but not the current `date`.
     * Technically: `true if current position is null and previous position is not null`. This field will be `null` if
     * `is_exit` is not provided for the dataset.
     *
     * @return isExit
     */
    public Boolean getIsExit() {
        return isExit;
    }

    public void setIsExit(Boolean isExit) {
        this.isExit = isExit;
    }

    public ChartPosition isReentry(Boolean isReentry) {
        this.isReentry = isReentry;
        return this;
    }

    /**
     * True if this entity did not appear on the Chart or Playlist the day before (`date - 1 day`), but did appear
     * sometime in the past (`previous_position is not null`).
     *
     * @return isReentry
     */
    public Boolean getIsReentry() {
        return isReentry;
    }

    public void setIsReentry(Boolean isReentry) {
        this.isReentry = isReentry;
    }

    public ChartPosition previousDate(LocalDate previousDate) {
        this.previousDate = JsonNullable.of(previousDate);
        return this;
    }

    /**
     * The most recent previous date the entity appeared on the Chart or Playlist.
     *
     * @return previousDate
     */


    public JsonNullable<LocalDate> getPreviousDate() {
        return previousDate;
    }

    public void setPreviousDate(JsonNullable<LocalDate> previousDate) {
        this.previousDate = previousDate;
    }

    public ChartPosition previousPosition(Integer previousPosition) {
        this.previousPosition = previousPosition;
        return this;
    }

    /**
     * The entity's position (or \"rank\") on the `previous_date`. The previous date is the latest date the entity
     * appears on the Chart or Playlist, before the current `date`.
     *
     * @return previousPosition
     */
    public Integer getPreviousPosition() {
        return previousPosition;
    }

    public void setPreviousPosition(Integer previousPosition) {
        this.previousPosition = previousPosition;
    }

    public ChartPosition trend(Integer trend) {
        this.trend = trend;
        return this;
    }

    /**
     * Positive or negative integer indicating the difference in position rank between the `previous_position` and
     * `current_position`. `trend = previous_position - current_position`
     *
     * @return trend
     */
    public Integer getTrend() {
        return trend;
    }

    public void setTrend(Integer trend) {
        this.trend = trend;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        ChartPosition chartPosition = (ChartPosition) o;
        return Objects.equals(this.current, chartPosition.current) &&
            Objects.equals(this.date, chartPosition.date) &&
            Objects.equals(this.dateGap, chartPosition.dateGap) &&
            Objects.equals(this.isEntry, chartPosition.isEntry) &&
            Objects.equals(this.isExit, chartPosition.isExit) &&
            Objects.equals(this.isReentry, chartPosition.isReentry) &&
            Objects.equals(this.previousDate, chartPosition.previousDate) &&
            Objects.equals(this.previousPosition, chartPosition.previousPosition) &&
            Objects.equals(this.trend, chartPosition.trend);
    }

    @Override
    public int hashCode() {
        return Objects.hash(current, date, dateGap, isEntry, previousDate, previousPosition, trend);
    }

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

        sb.append("    current: ").append(toIndentedString(current)).append("\n");
        sb.append("    date: ").append(toIndentedString(date)).append("\n");
        sb.append("    dateGap: ").append(toIndentedString(dateGap)).append("\n");
        sb.append("    isEntry: ").append(toIndentedString(isEntry)).append("\n");
        sb.append("    isExit: ").append(toIndentedString(isExit)).append("\n");
        sb.append("    isReentry: ").append(toIndentedString(isReentry)).append("\n");
        sb.append("    previousDate: ").append(toIndentedString(previousDate)).append("\n");
        sb.append("    previousPosition: ").append(toIndentedString(previousPosition)).append("\n");
        sb.append("    trend: ").append(toIndentedString(trend)).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    ");
    }
}

