package io.delphi.qa.auto.awsmfrw.models.l2;

import com.amazonaws.util.StringUtils;
import com.google.common.base.MoreObjects;
import com.google.gson.annotations.SerializedName;
import io.delphi.qa.auto.awsmfrw.common_baby.IsaCommonMethods;
import lombok.*;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

@Getter
@With
// @ToString
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
public class MlFw_L2ArtistOnboardingReport implements Supplier<Integer> {

  @SerializedName("artist_name")
  protected String artistName;

  @SerializedName("chartmetric_id")
  protected String chartmetricId;

  @SerializedName("gras_id")
  protected String grasId;

  // sony
  @SerializedName("gras_id_in_sony_artist")
  List<Map<String, String>> grasIdInSonyArtist;

  @SerializedName("gras_id_occurrence_in_sony_artist")
  Long grasIdOccurrenceInSonyArtist;

  @SerializedName("chartmetric_id_in_sony_artist")
  List<Map<String, String>> chartmetricIdInSonyArtist;

  @SerializedName("chartmetric_id_occurrence_in_sony_artist")
  Long chartmetricIdOccurrenceInSonyArtist;

  @SerializedName("artist_name_in_sony_artist")
  List<Map<String, String>> artistNameInSonyArtist;

  @SerializedName("artist_name_occurrence_in_sony_artist")
  Long artistNameOccurrenceInSonyArtist;

  @SerializedName("gras_id_in_artist_priority")
  List<Map<String, String>> grasIdInArtistPriority;

  @SerializedName("gras_id_occurrence_in_artist_priority")
  Long grasIdOccurrenceInArtistPriority;

  @SerializedName("chartmetric_id_in_artist_priority")
  List<Map<String, String>> chartmetricIdInArtistPriority;

  @SerializedName("chartmetric_id_occurrence_in_artist_priority")
  Long chartmetricIdOccurrenceInArtistPriority;

  @SerializedName("artist_name_in_artist_priority")
  List<Map<String, String>> artistNameInArtistPriority;

  @SerializedName("artist_name_occurrence_in_artist_priority")
  Long artistNameOccurrenceInArtistPriority;
  // spotify
  @SerializedName("chartmetric_id_in_spotify_artist")
  List<Map<String, String>> chartmetricIdInSpotifyArtist;

  @SerializedName("spotify_artist_id_occurrence_in_spotify_artist")
  Long spotifyArtistIdOccurrenceInSpotifyArtist;

  @SerializedName("spotify_artist_name_occurrence_in_spotify_artist")
  Long spotifyArtistNameOccurrenceInSpotifyArtist;
  // apple
  @SerializedName("chartmetric_id_in_itunes_artist")
  List<Map<String, String>> chartmetricIdInItunesArtist;

  @SerializedName("itunes_artist_id_occurrence_in_itunes_artist")
  Long itunesArtistIdOccurrenceInItunesArtist;
  //  social
  @SerializedName("chartmetric_id_in_cm_url_of_bandsintown")
  List<Map<String, String>> chartmetricIdInCmUrlOfBandsInTown;

  @SerializedName("chartmetric_id_in_cm_url_of_deezer")
  List<Map<String, String>> chartmetricIdInCmUrlOfDeezer;

  @SerializedName("chartmetric_id_in_cm_url_of_facebook")
  List<Map<String, String>> chartmetricIdInCmUrlOfFacebook;

  @SerializedName("chartmetric_id_in_cm_url_of_instagram")
  List<Map<String, String>> chartmetricIdInCmUrlOfInstagram;

  @SerializedName("chartmetric_id_in_cm_url_of_spotify")
  List<Map<String, String>> chartmetricIdInCmUrlOfSpotify;

  @SerializedName("chartmetric_id_in_cm_url_of_twitter")
  List<Map<String, String>> chartmetricIdInCmUrlOfTwitter;

  @SerializedName("chartmetric_id_in_cm_url_of_wikipedia")
  List<Map<String, String>> chartmetricIdInCmUrlOfWikipedia;

  @SerializedName("chartmetric_id_in_cm_url_of_youtube")
  List<Map<String, String>> chartmetricIdInCmUrlOfYoutube;

  public int getSpotifyArtistIdOccurrenceInSpotifyArtist() {
    return (int)
        chartmetricIdInSpotifyArtist.stream()
            .filter(
                m ->
                    m.entrySet().stream()
                        .anyMatch(
                            e ->
                                e.getKey().equalsIgnoreCase("spotify_artist_id")
                                    && e.getValue() != null))
            .count();
  }

  public int getSpotifyArtistNameOccurrenceInSpotifyArtist() {
    return (int)
        chartmetricIdInSpotifyArtist.stream()
            .filter(
                m ->
                    m.entrySet().stream()
                        .anyMatch(
                            e ->
                                e.getKey().equalsIgnoreCase("artist_name") && e.getValue() != null))
            .count();
  }

  public int getItunesArtistIdOccurrenceInItunesArtist() {
    return (int)
        chartmetricIdInItunesArtist.stream()
            .filter(
                m ->
                    m.entrySet().stream()
                        .anyMatch(
                            e ->
                                e.getKey().equalsIgnoreCase("itunes_artist_id")
                                    && e.getValue() != null))
            .count();
  }

  public int getAppleArtistNameOccurrenceInItunesArtist() {
    return (int)
        chartmetricIdInItunesArtist.stream()
            .filter(
                m ->
                    m.entrySet().stream()
                        .anyMatch(e -> e.getKey().equalsIgnoreCase("name") && e.getValue() != null))
            .count();
  }

  @SerializedName("apple_artist_name_occurrence_in_itunes_artist")
  Long appleArtistNameOccurrenceInItunesArtist;

  @Override
  public String toString() {
    return MoreObjects.toStringHelper(this)
        .add("artistName", artistName)
        .add("chartmetricId", chartmetricId)
        .add("grasId", grasId)
        .add("grasIdInSonyArtist", grasIdInSonyArtist)
        .add("grasIdOccurrenceInSonyArtist", grasIdOccurrenceInSonyArtist)
        .add("chartmetricIdInSonyArtist", chartmetricIdInSonyArtist)
        .add("chartmetricIdOccurrenceInSonyArtist", chartmetricIdOccurrenceInSonyArtist)
        .add("artistNameInSonyArtist", artistNameInSonyArtist)
        .add("artistNameOccurrenceInSonyArtist", artistNameOccurrenceInSonyArtist)
        .add("grasIdInArtistPriority", grasIdInArtistPriority)
        .add("grasIdOccurrenceInArtistPriority", grasIdOccurrenceInArtistPriority)
        .add("chartmetricIdInArtistPriority", chartmetricIdInArtistPriority)
        .add("chartmetricIdOccurrenceInArtistPriority", chartmetricIdOccurrenceInArtistPriority)
        .add("artistNameInArtistPriority", artistNameInArtistPriority)
        .add("artistNameOccurrenceInArtistPriority", artistNameOccurrenceInArtistPriority)
        .add("chartmetricIdInSpotifyArtist", chartmetricIdInSpotifyArtist)
        .add("spotifyArtistIdOccurrenceInSpotifyArtist", spotifyArtistIdOccurrenceInSpotifyArtist)
        .add(
            "spotifyArtistNameOccurrenceInSpotifyArtist",
            spotifyArtistNameOccurrenceInSpotifyArtist)
        .add("chartmetricIdInItunesArtist", chartmetricIdInItunesArtist)
        .add("itunesArtistIdOccurrenceInItunesArtist", itunesArtistIdOccurrenceInItunesArtist)
        .add("chartmetricIdInCmUrlOfBandsInTown", chartmetricIdInCmUrlOfBandsInTown)
        .add("chartmetricIdInCmUrlOfDeezer", chartmetricIdInCmUrlOfDeezer)
        .add("chartmetricIdInCmUrlOfFacebook", chartmetricIdInCmUrlOfFacebook)
        .add("chartmetricIdInCmUrlOfInstagram", chartmetricIdInCmUrlOfInstagram)
        .add("chartmetricIdInCmUrlOfSpotify", chartmetricIdInCmUrlOfSpotify)
        .add("chartmetricIdInCmUrlOfTwitter", chartmetricIdInCmUrlOfTwitter)
        .add("chartmetricIdInCmUrlOfWikipedia", chartmetricIdInCmUrlOfWikipedia)
        .add("chartmetricIdInCmUrlOfYoutube", chartmetricIdInCmUrlOfYoutube)
        .add("appleArtistNameOccurrenceInItunesArtist", appleArtistNameOccurrenceInItunesArtist)
        .toString();
  }

  public String output() {
    Map<String, Object> hashMap = getReportMap();
    //    return hashMap.values().stream().map(Object::toString).collect(Collectors.joining(","));
    return hashMap.toString();
  }

  private LinkedHashMap<String, Object> getReportMap() {
    return new LinkedHashMap<String, Object>() {
      {
        put("gras_id", formatSqlValue(getGrasId()));
        put("chartmetric_id", formatSqlValue(getChartmetricId()));
        put("artist_name", formatSqlValue(getArtistName()));
        List<String> spotifyArtistIds =
            IsaCommonMethods.collectValuesInListOfMapsByKey(
                getChartmetricIdInSpotifyArtist(), "SPOTIFY_ARTIST_ID");
        put("spotify_id", spotifyArtistIds);
        List<String> itunesArtistIds =
            IsaCommonMethods.collectValuesInListOfMapsByKey(
                getChartmetricIdInItunesArtist(), "ITUNES_ARTIST_ID");
        put("apple_id", itunesArtistIds);
        List<String> updateDates =
            IsaCommonMethods.collectValuesInListOfMapsByKey(
                getChartmetricIdInArtistPriority(), "UPDATE_DATE");
        put("current_date", updateDates.size() > 0 ? updateDates.get(0) : "current_date()");
        put("status", "'ACTIVE'");
        put("bandsintown", getChartmetricIdInCmUrlOfBandsInTown().size());
        put("deezer", getChartmetricIdInCmUrlOfDeezer().size());
        put("facebook", getChartmetricIdInCmUrlOfFacebook().size());
        put("instagram", getChartmetricIdInCmUrlOfInstagram().size());
        put("spotify", getChartmetricIdInCmUrlOfSpotify().size());
        put(
            "twitter",
            getChartmetricIdInCmUrlOfTwitter() != null
                ? getChartmetricIdInCmUrlOfTwitter().size()
                : 0);
        put("wikipedia", getChartmetricIdInCmUrlOfWikipedia().size());
        put("youtube", getChartmetricIdInCmUrlOfYoutube().size());
      }
    };
  }

  private String formatSqlValue(String value) {
    return StringUtils.isNullOrEmpty(value) ? "NULL" : String.format("'%s'", value);
  }

  public String insertSonyArtist() {
    LinkedHashMap<String, Object> reportMap = getReportMap();
    return String.format(
        "insert into \"DELPHI_EXPLORATION\".\"CHARTMETRIC_SYS\".\"SONY_ARTIST\""
            + "\n(GRAS_ID, ARTIST_NAME, SPOTIFY_ID, APPLE_ID, CHARTMETRIC_ID, UPDATE_DATE)"
            + "\nvalues (%1$s,%2$s,%3$s,%4$s,%5$s,%6$s)",
        reportMap.get("gras_id"),
        reportMap.get("artist_name"),
        reportMap.get("spotify_id"),
        reportMap.get("apple_id"),
        reportMap.get("chartmetric_id"),
        reportMap.get("current_date"));
  }

  public String insertArtistPriority() {
    LinkedHashMap<String, Object> reportMap = getReportMap();
    //    reportMap.entrySet().stream().filter(o -> o.getValue().toString().contains("_id"))
    return String.format(
        "insert into \"DELPHI_EXPLORATION\".\"CHARTMETRIC_SYS\".\"ARTIST_PRIORITY\""
            + "\n(GRAS_ID, ARTIST_NAME, CHARTMETRIC_ID, STATUS, BANDSINTOWN, DEEZER, FACEBOOK, INSTAGRAM, SPOTIFY, TWITTER, WIKIPEDIA, YOUTUBE)"
            + "\nvalues (%1$s,%2$s,%3$s,%4$s,%5$s,%6$s,%7$s,%8$s,%9$s,%10$s,%11$s,%12$s')",
        reportMap.get("gras_id"),
        reportMap.get("artist_name"),
        reportMap.get("chartmetric_id"),
        reportMap.get("status"),
        reportMap.get("bandsintown"),
        reportMap.get("deezer"),
        reportMap.get("facebook"),
        reportMap.get("instagram"),
        reportMap.get("spotify"),
        reportMap.get("twitter"),
        reportMap.get("wikipedia"),
        reportMap.get("youtube"));
  }

  @Override
  public Integer get() {
    return this.grasIdInSonyArtist.size()
        + this.chartmetricIdInSonyArtist.size()
        + this.artistNameInSonyArtist.size()
        + this.grasIdInArtistPriority.size()
        + this.chartmetricIdInArtistPriority.size()
        + this.artistNameInArtistPriority.size()
        + this.getItunesArtistIdOccurrenceInItunesArtist()
        + this.getAppleArtistNameOccurrenceInItunesArtist()
        + this.getSpotifyArtistIdOccurrenceInSpotifyArtist()
        + this.getSpotifyArtistNameOccurrenceInSpotifyArtist();
  }

  public String updateSonyArtist() {
    LinkedHashMap<String, Object> reportMap = getReportMap();
    //    reportMap.entrySet().stream().filter(o -> o.getValue().toString().contains("_id"))
    String format =
        String.format(
            "update \"DELPHI_EXPLORATION\".\"CHARTMETRIC_SYS\".\"SONY_ARTIST\""
                + "\nset ARTIST_NAME=%1$s, GRAS_ID=%2$s, SPOTIFY_ID=%4$s, APPLE_ID=%5$s, UPDATE_DATE=%6$s"
                + "\nwhere CHARTMETRIC_ID=%3$s",
            reportMap.get("artist_name"),
            reportMap.get("gras_id"),
            reportMap.get("chartmetric_id"),
            reportMap.get("spotify_id"),
            reportMap.get("apple_id"),
            reportMap.get("current_date"));
    return format;
  }

  public String updateArtistPriority() {
    LinkedHashMap<String, Object> reportMap = getReportMap();
    //    reportMap.entrySet().stream().filter(o -> o.getValue().toString().contains("_id"))
    return String.format(
        "update \"DELPHI_EXPLORATION\".\"CHARTMETRIC_SYS\".\"ARTIST_PRIORITY\""
            + "\nset ARTIST_NAME=%1$s, GRAS_ID=%2$s, STATUS=%4$s, BANDSINTOWN=%5$s, DEEZER=%6$s, FACEBOOK=%7$s, INSTAGRAM=%8$s, SPOTIFY=%9$s, TWITTER=%10$s, WIKIPEDIA=%11$S, YOUTUBE=%12$s"
            + "\nwhere CHARTMETRIC_ID='%3$s'",
        reportMap.get("artist_name"),
        reportMap.get("gras_id"),
        reportMap.get("chartmetric_id"),
        reportMap.get("status"),
        reportMap.get("bandsintown"),
        reportMap.get("deezer"),
        reportMap.get("facebook"),
        reportMap.get("instagram"),
        reportMap.get("spotify"),
        reportMap.get("twitter"),
        reportMap.get("wikipedia"),
        reportMap.get("youtube"));
  }
}
