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

import com.fasterxml.jackson.annotation.JsonProperty;

import org.springframework.format.annotation.DateTimeFormat;

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

import io.delphiplatform.api.v3.rdb.entity.video.AbstractChartSummaryReportEntity;
import io.delphiplatform.api.v3.rdb.entity.video.TrendingVideoChartSummaryReportEntity;

/**
 * ChartPositionSummary
 */
public class ChartPositionSummary {

    @JsonProperty("earliest_position")
    private Integer earliestPosition;

    @JsonProperty("earliest_position_date")
    private LocalDate earliestPositionDate;

    @JsonProperty("latest_position")
    private Integer latestPosition;

    @JsonProperty("latest_position_date")
    private LocalDate latestPositionDate;

    @JsonProperty("max_position")
    private Integer maxPosition;

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

    @JsonProperty("min_position")
    private Integer minPosition;

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

    @JsonProperty("total_days")
    private Integer totalDays;

    public static ChartPositionSummary of(TrendingVideoChartSummaryReportEntity entity) {
        if(entity == null){
            return null;
        }

        return new ChartPositionSummary()
            .earliestPosition(entity.getEarliestPosition())
            .earliestPositionDate(entity.getEarliestPositionDate())
            .latestPosition(entity.getLatestPosition())
            .latestPositionDate(entity.getLatestPositionDate())
            .maxPosition(entity.getMaxPosition())
            .maxPositionDate(entity.getMaxPositionDate())
            .minPosition(entity.getMinPosition())
            .minPositionDate(entity.getMinPositionDate())
            .totalDays(entity.getTotalDays());
    }

    public static <T extends AbstractChartSummaryReportEntity> void fill(ChartPositionSummary summary, T entity) {
        summary.earliestPosition(entity.getEarliestPosition())
            .earliestPositionDate(entity.getEarliestPositionDate())
            .latestPosition(entity.getLatestPosition())
            .latestPositionDate(entity.getLatestPositionDate())
            .maxPosition(entity.getMaxPosition())
            .maxPositionDate(entity.getMaxPositionDate())
            .minPosition(entity.getMinPosition())
            .minPositionDate(entity.getMinPositionDate())
            .totalDays(entity.getTotalDays());
    }

    public ChartPositionSummary maxPosition(Integer maxPosition) {
        this.maxPosition = maxPosition;
        return this;
    }


    public ChartPositionSummary earliestPosition(Integer earliestPosition) {
        this.earliestPosition = earliestPosition;
        return this;
    }

    /**
     * Earliest or \"entry\" position, the first time the entity appeared on the Chart or Playlist.
     *
     * @return earliestPosition
     */
    public Integer getEarliestPosition() {
        return earliestPosition;
    }

    public void setEarliestPosition(Integer earliestPosition) {
        this.earliestPosition = earliestPosition;
    }

    public ChartPositionSummary earliestPositionDate(LocalDate earliestPositionDate) {
        this.earliestPositionDate = earliestPositionDate;
        return this;
    }

    /**
     * Date of the earliest or \"entry\" position to the Chart or Playlist.
     *
     * @return earliestPositionDate
     */
    public LocalDate getEarliestPositionDate() {
        return earliestPositionDate;
    }

    public void setEarliestPositionDate(LocalDate earliestPositionDate) {
        this.earliestPositionDate = earliestPositionDate;
    }

    public ChartPositionSummary latestPosition(Integer latestPosition) {
        this.latestPosition = latestPosition;
        return this;
    }

    /**
     * The latest (most recent/\"current\") position for the entity on the Chart or Playlist.
     *
     * @return latestPosition
     */
    public Integer getLatestPosition() {
        return latestPosition;
    }

    public void setLatestPosition(Integer latestPosition) {
        this.latestPosition = latestPosition;
    }

    public ChartPositionSummary latestPositionDate(LocalDate latestPositionDate) {
        this.latestPositionDate = latestPositionDate;
        return this;
    }

    /**
     * Date of the latest (most recent/\"current\") position for the entity on the Chart or Playlist.
     *
     * @return latestPositionDate
     */
    public LocalDate getLatestPositionDate() {
        return latestPositionDate;
    }

    public void setLatestPositionDate(LocalDate latestPositionDate) {
        this.latestPositionDate = latestPositionDate;
    }


    /**
     * Lowest ranking position (highest number) within the Chart or Playlist.
     *
     * @return maxPosition
     */
    public Integer getMaxPosition() {
        return maxPosition;
    }

    public void setMaxPosition(Integer maxPosition) {
        this.maxPosition = maxPosition;
    }

    public ChartPositionSummary maxPositionDate(LocalDate maxPositionDate) {
        this.maxPositionDate = maxPositionDate;
        return this;
    }

    /**
     * Date of the lowest ranking position (highest number) within the Chart or Playlist.
     *
     * @return maxPositionDate
     */
    public LocalDate getMaxPositionDate() {
        return maxPositionDate;
    }

    public void setMaxPositionDate(LocalDate maxPositionDate) {
        this.maxPositionDate = maxPositionDate;
    }

    public ChartPositionSummary minPosition(Integer minPosition) {
        this.minPosition = minPosition;
        return this;
    }

    /**
     * Highest (or \"peak\") ranking position (lowest number) within the Chart or Playlist.
     *
     * @return minPosition
     */
    public Integer getMinPosition() {
        return minPosition;
    }

    public void setMinPosition(Integer minPosition) {
        this.minPosition = minPosition;
    }

    public ChartPositionSummary minPositionDate(LocalDate minPositionDate) {
        this.minPositionDate = minPositionDate;
        return this;
    }

    /**
     * Date of the highest (or \"peak\") ranking position (lowest number) within the Chart or Playlist.
     *
     * @return minPositionDate
     */
    public LocalDate getMinPositionDate() {
        return minPositionDate;
    }

    public void setMinPositionDate(LocalDate minPositionDate) {
        this.minPositionDate = minPositionDate;
    }

    public ChartPositionSummary totalDays(Integer totalDays) {
        this.totalDays = totalDays;
        return this;
    }

    /**
     * Total number of days the entity has appeared on the Chart or Playlist (all-time).
     *
     * @return totalDays
     */
    public Integer getTotalDays() {
        return totalDays;
    }

    public void setTotalDays(Integer totalDays) {
        this.totalDays = totalDays;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        ChartPositionSummary chartPositionSummary = (ChartPositionSummary) o;
        return Objects.equals(this.maxPosition, chartPositionSummary.maxPosition) &&
            Objects.equals(this.maxPositionDate, chartPositionSummary.maxPositionDate) &&
            Objects.equals(this.minPosition, chartPositionSummary.minPosition) &&
            Objects.equals(this.minPositionDate, chartPositionSummary.minPositionDate) &&
            Objects.equals(this.totalDays, chartPositionSummary.totalDays);
    }

    @Override
    public int hashCode() {
        return Objects.hash(maxPosition, maxPositionDate, minPosition, minPositionDate, totalDays);
    }

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

        sb.append("    maxPosition: ").append(toIndentedString(maxPosition)).append("\n");
        sb.append("    maxPositionDate: ").append(toIndentedString(maxPositionDate)).append("\n");
        sb.append("    minPosition: ").append(toIndentedString(minPosition)).append("\n");
        sb.append("    minPositionDate: ").append(toIndentedString(minPositionDate)).append("\n");
        sb.append("    totalDays: ").append(toIndentedString(totalDays)).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    ");
    }
}

