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

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

import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

import io.delphiplatform.api.util.model.ModelUtils;
import io.delphiplatform.api.v3.rdb.entity.spotify.SpotifyPlaylistTrackEntity;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@JsonPropertyOrder(alphabetic = true)
@EqualsAndHashCode
public class SpotifyTrack {

    @JsonProperty("track_id")
    private String trackId;

    @JsonProperty("name")
    private String name;

    @JsonProperty("image_url")
    private String imageUrl;

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

    @JsonProperty("is_sony")
    private boolean isSony;

    @JsonProperty("isrc")
    private String isrc;

    @JsonProperty("track_popularity")
    private Long trackPopularity;

    @JsonProperty("artists")
    private List<SpotifyArtist> artists;

    @JsonProperty("album")
    private SpotifyAlbum album;

    public static SpotifyTrack from(SpotifyPlaylistTrackEntity spotifyPlaylistTrack) {
        if (spotifyPlaylistTrack == null) {
            return null;
        }
        SpotifyTrack spotifyTrack = new SpotifyTrack();
        spotifyTrack.setTrackId(spotifyPlaylistTrack.getSpotifyTrackId());
        spotifyTrack.setSony(spotifyPlaylistTrack.isSony());
        spotifyTrack.setIsrc(spotifyPlaylistTrack.getIsrc());
        spotifyTrack.setTrackPopularity(spotifyPlaylistTrack.getTrackPopularity());
        spotifyTrack.setName(spotifyPlaylistTrack.getName());

        SpotifyAlbum spotifyAlbum = new SpotifyAlbum();
        spotifyTrack.setAlbum(spotifyAlbum);
        if (spotifyPlaylistTrack.getSpotifyAlbum() != null) {
            spotifyAlbum.setAlbumId(spotifyPlaylistTrack.getSpotifyAlbum().getAlbumId());
            spotifyAlbum.setName(spotifyPlaylistTrack.getSpotifyAlbum().getName());
            spotifyAlbum.setImage(spotifyPlaylistTrack.getSpotifyAlbum().getImageUrl());
            spotifyAlbum.setUpc(spotifyPlaylistTrack.getSpotifyAlbum().getUpc());
            spotifyAlbum.setReleaseDate(spotifyPlaylistTrack.getSpotifyAlbum().getReleaseDate());
        }

        String trackImageUrl = spotifyPlaylistTrack.getImageUrl() != null
            ? spotifyPlaylistTrack.getImageUrl()
            : spotifyAlbum.getImage();

        LocalDate trackReleaseDate = spotifyPlaylistTrack.getReleaseDate() != null
            ? spotifyPlaylistTrack.getReleaseDate()
            : spotifyAlbum.getReleaseDate();

        spotifyTrack.setImageUrl(trackImageUrl);
        spotifyTrack.setReleaseDate(trackReleaseDate);

        List<SpotifyArtist> spotifyArtists = spotifyPlaylistTrack.getArtists().stream()
            .map(a -> SpotifyArtist.builder()
                .artistId(a.getSpotifyArtistId())
                .name(a.getName())
                .url(a.getUrl() != null
                    ? a.getUrl()
                    : ModelUtils.formatSpotifyArtistUrl(a.getSpotifyArtistId()))
                .build())
            .collect(Collectors.toList());

        spotifyTrack.setArtists(spotifyArtists);

        return spotifyTrack;
    }
}
