import spotipy
import emoji
import spotipy.util as util
from random import randint
from spotipy.oauth2 import SpotifyClientCredentials

''' 
Script takes in array of artists. 
With this input, it produces a playlist based on the associated Spotify-generated recommendations.
'''

client_credentials_manager = SpotifyClientCredentials()
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
sp.trace = False

# Seed artists for playlist
artist_list = ["Prince", "The Weeknd", "Daft Punk", "Press Club", "Cub Sport"]
# Variable for Spotify user name
my_username = ''


def artist_recommender(list_of_artists, input_username, input_playlist_name=None):
    # Define list to store recommended track IDs
    output_track_id_list = []

    # Function used to find artist exactly matching input, returning first results if none is found
    def exact_matcher(match_term, item_list):
        if len(item_list) > 0:
            for i in item_list:
                if i != match_term:
                    exact_match_flag = 0
                else:
                    exact_match_flag = 1
                    break
            if exact_match_flag == 1:
                return i
            else:
                return None
        else:
            return None

    # Function used to access artist object through Spotify
    def get_artist(name):
        results = sp.search(q='artist:' + name, type='artist')
        items = results['artists']['items']
        results_list = [nm['name'] for nm in items]
        exact_match = exact_matcher(match_term=name, item_list=results_list)
        if len(items) > 0:
            if exact_match:
                print("Input: " + name + ". Exact match artist found!")
                exact_match_output = [nm for nm in items if nm['name'] == exact_match]
                return exact_match_output[0]
            else:
                print("No exact match found. Returning results for first close match: " + items[0]['name'])
                return items[0]
        else:
            print(name + " not found. " + emoji.emojize(':pensive:', use_aliases=True))
            return None

    # Function used to add recommended tracks based on input artist
    def store_recommendations_for_artist(artist):
        results = sp.recommendations(seed_artists=[artist['id']])
        for track in results['tracks']:
            output_track_id_list.append(track['id'])

    # Function used to create new playlist
    def playlist_init(playlist_name="App Generated Playlist " + str(randint(0, 1000)),
                      playlist_description="Playlist generated by spotipy."):
        scope = "playlist-modify-public"
        token = util.prompt_for_user_token(input_username, scope)

        if token:
            sp = spotipy.Spotify(auth=token)
            sp.trace = False
            playlists = sp.user_playlist_create(input_username, playlist_name,
                                                description=playlist_description)
            print("Playlist successfully created with ID " + playlists['id'] + ".")
            return playlists['id']
        else:
            print("Can't get token for ", input_username)

    # Function used to add recommended tracks to newly-created playlist
    def playlist_creator(track_list, playlist_id):
        scope = 'playlist-modify-public'
        token = util.prompt_for_user_token(input_username, scope)

        if token:
            sp = spotipy.Spotify(auth=token)
            sp.trace = False
            results = sp.user_playlist_add_tracks(input_username, playlist_id, track_list)
            print(results)
        else:
            print("Can't get token for", input_username)

    # Iterate through list of input artists
    for performer in list_of_artists:
        # Store artist object as variable
        artist = get_artist(performer)
        # If artist is found, add recommended songs to list
        if artist:
            store_recommendations_for_artist(artist)
        else:
            print("Can't find that artist.")
            continue

    # Create new playlist with input playlist if specified
    if input_playlist_name:
        new_playlist_id = playlist_init(playlist_name=input_playlist_name)
    else:
        new_playlist_id = playlist_init()

    # Add list of recommended tracks to playlist
    playlist_creator(output_track_id_list, new_playlist_id)


artist_recommender(artist_list, my_username)
