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

import com.google.common.collect.ImmutableMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nullable;

import io.delphiplatform.api.v3.constant.DspConstants;
import io.delphiplatform.api.v3.model.ImageSimple;
import io.delphiplatform.api.v3.model.video.VideoImage;
import io.delphiplatform.api.v3.model.video.YouTubeThumbnails;
import io.delphiplatform.api.v3.rdb.entity.ArtistEntity;
import io.delphiplatform.api.v3.rdb.entity.PlaylistEntity;
import io.delphiplatform.api.v3.rdb.entity.PlaylistPublicViewEntity;
import io.delphiplatform.api.v3.rdb.entity.apple.music.PlaylistPublicAppleMusicEntity;
import io.delphiplatform.api.v3.rdb.entity.spotify.PlaylistPublicSpotifyEntity;
import io.delphiplatform.api.v3.rdb.entity.video.ChartmetricVideoEntity;
import io.delphiplatform.api.v3.rdb.entity.video.VideoEntity;
import io.delphiplatform.api.v3.search.entity.ArtistDocumentEntity;

@Service
public class ImageService {

    private static final Set<String> DSPS_WITH_ARTWORK_URL_AVAILABLE = Set.of(DspConstants.AMAZON);

    @Value("${delphi.atlas-service.host}")
    private String atlasHost;
    @Value("${delphi.youtube-image-service.host}")
    private String ytImageHost;

    private Map<String, String> playlistDspParts = ImmutableMap.of("spotify", "by_spotify_id",
        "apple", "by_apple_music_id");

    public ImageSimple resolveImage(ArtistEntity artist) {
        if (artist.getParticipNo() == null) {
            return null;
        }
        return new ImageSimple().uri(URI.create(String.format("%s/artists/by_gras_participant_id/%s",
            atlasHost, artist.getParticipNo())));
    }

    public ImageSimple resolveImage(PlaylistEntity playlist) {
        if (playlist.getDsp() == null || playlist.getDspPlaylistId() == null) {
            return null;
        }

        return resolveImage(playlist.getDsp().getDspId(), playlist.getDspPlaylistId(), null, playlist.getArtworkUrl());
    }

    public ImageSimple resolveImage(PlaylistPublicAppleMusicEntity playlist) {
        if (playlist.getDsp() == null || playlist.getDspPlaylistId() == null) {
            return null;
        }

        return resolveImage(playlist.getDsp().getDspId(), playlist.getDspPlaylistId(), playlist.getCountryCode(), playlist.getArtworkUrl());
    }

    public ImageSimple resolveImage(PlaylistPublicSpotifyEntity playlist) {
        if (playlist.getDsp() == null || playlist.getDspPlaylistId() == null) {
            return null;
        }

        return resolveImage(playlist.getDsp().getDspId(), playlist.getDspPlaylistId(), null, playlist.getArtworkUrl());
    }

    public ImageSimple resolveImage(String dspId, String dspPlaylistId, @Nullable String countryCode, @Nullable String artworkUrl) {
        if (artworkUrl != null) {
            return new ImageSimple().uri(URI.create(artworkUrl));
        }

        if (DSPS_WITH_ARTWORK_URL_AVAILABLE.contains(dspId) || dspId == null || dspPlaylistId == null) {
            return null;
        }

        String dspPart = playlistDspParts.get(dspId);
        String urlParams = countryCode == null ? StringUtils.EMPTY : "?storefront=" + countryCode;

        return new ImageSimple()
            .uri(URI.create(String.format("%s/playlists/%s/%s%s", atlasHost, dspPart, dspPlaylistId, urlParams)));
    }

    public ImageSimple resolveImage(ArtistDocumentEntity artist) {
        if (artist.getParticipNo() == null) {
            return null;
        }
        return new ImageSimple().uri(URI.create(String.format("%s/artists/by_gras_participant_id/%s",
            atlasHost, artist.getParticipNo())));
    }

    public YouTubeThumbnails resolveImage(VideoEntity entity) {
        return resolveVideoImage(entity.getDspVideoId());
    }

    public YouTubeThumbnails resolveImage(ChartmetricVideoEntity entity) {
        return resolveVideoImage(entity.getDspVideoId());
    }

    public YouTubeThumbnails resolveVideoImage(String videoId) {
        return new YouTubeThumbnails()
            .defaultImage(new VideoImage().url(getYoutubeDefaultImageUrl(videoId)).width(120).height(90))
            .medium(new VideoImage().url(getYoutubeMediumImageUrl(videoId)).width(320).height(180))
            .high(new VideoImage().url(getYoutubeHighImageUrl(videoId)).width(480).height(360));
    }

    private String getYoutubeDefaultImageUrl(String videoId) {
        return String.format("%s/vi/%s/default.jpg", ytImageHost, videoId);
    }

    private String getYoutubeMediumImageUrl(String videoId) {
        return String.format("%s/vi/%s/mqdefault.jpg", ytImageHost, videoId);
    }

    private String getYoutubeHighImageUrl(String videoId) {
        return String.format("%s/vi/%s/hqdefault.jpg", ytImageHost, videoId);
    }
}
