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

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.time.LocalDateTime;
import java.util.Map;

import io.delphiplatform.api.util.model.ModelUtils;
import io.delphiplatform.api.v3.constant.ApplicationConstants;
import io.delphiplatform.api.v3.model.PlaylistDates;
import io.delphiplatform.api.v3.model.PlaylistDatesAwareModel;
import io.delphiplatform.api.v3.model.PlaylistStreamingForPeriodsInfo;
import io.delphiplatform.api.v3.model.PublicPlaylist;
import io.delphiplatform.api.v3.model.PublicPlaylistableModel;
import io.delphiplatform.api.v3.model.StreamingInfoAwareModel;
import io.delphiplatform.api.v3.model.TrackAwareModel;
import io.delphiplatform.api.v3.model.TrackSimple;
import io.delphiplatform.api.v3.rdb.entity.PlaylistTrackLifetimePublicProjection;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Builder
@Getter
@Setter
@EqualsAndHashCode
public class PublicPlaylistTrackPreviousPosition implements PublicPlaylistableModel, TrackAwareModel, PlaylistDatesAwareModel,
    StreamingInfoAwareModel {

    //if serialization is introduced (for Spotify DSP) - return field through transformation (see DAPD-2428)
    @JsonIgnore
    private String countryCode;

    @JsonProperty("dsp")
    private String dsp;

    @JsonProperty("earliest_position_date_time")
    @JsonFormat(shape = Shape.STRING, pattern = ApplicationConstants.ISO_DATE_TIME_PATTERN)
    private LocalDateTime earliestPositionDateTime;

    @JsonProperty("removed_date_time")
    @JsonFormat(shape = Shape.STRING, pattern = ApplicationConstants.ISO_DATE_TIME_PATTERN)
    private LocalDateTime removedDateTime;

    @JsonProperty("isrc")
    private String isrc;

    @JsonProperty("num_days_on")
    private Long numDaysOn;

    @JsonProperty("playlist_id")
    private String playlistId;

    @JsonProperty("playlist")
    private PublicPlaylist playlist;

    //'technical' playlist object that wont be serialized/returned to client etc.
    @JsonIgnore
    private PublicPlaylist transientPlaylist;

    @JsonProperty("track")
    private TrackSimple track;

    @JsonProperty("playlist_dates")
    private PlaylistDates playlistDates;

    @JsonProperty("streaming_info")
    private Map<String, PlaylistStreamingForPeriodsInfo> streamingInfo;

    public static PublicPlaylistTrackPreviousPosition from(PlaylistTrackLifetimePublicProjection projection) {
        if (projection == null) {
            return null;
        }

        return PublicPlaylistTrackPreviousPosition.builder()
            .dsp(projection.getDsp())
            .isrc(projection.getIsrc())
            .playlistId(projection.getPlaylistId())
            .countryCode(projection.getCountryCode())
            .earliestPositionDateTime(projection.getEarliestDateTime())
            .removedDateTime(projection.getLatestDateTime())
            .numDaysOn(ModelUtils.getTrackDaysOnPlaylist(
                projection.getEarliestDateTime(),
                projection.getLatestDateTime()
            ))
            .build();
    }
}
