package main

import (
    "encoding/json"
    // "log"
    "fmt"
    "net/http"
    "github.com/zmb3/spotify"
    "io/ioutil"
)

const baseURL_track = "https://api.spotify.com/v1/tracks/"
const baseURL_playlist = "https://api.spotify.com/v1/playlists/"
const baseURL_playlists = "https://api.spotify.com/v1/me/playlists"

func get_spotify_auth() (auth spotify.Authenticator){
    auth = spotify.NewAuthenticator(redirectURI, spotify.ScopeUserReadPrivate, spotify.ScopePlaylistReadPrivate, spotify.ScopePlaylistReadCollaborative, spotify.ScopeUserLibraryRead)

    return
}

// TODO: write this fkn func
func check_if_track_is_valid(track_id string) (state bool) {
    state = true
    
    // url := baseURL_track + track_id

    // httpClient := &http.Client{}
    // req, _ := http.NewRequest("GET", url, nil)
    // req.Header.Set("Authorization", "Bearer "+oauthToken)
    // res, _ := httpClient.Do(req)

    // body, _ := ioutil.ReadAll(res.Body)
    // data := new(spotifyTrack)
    // json.Unmarshal(body, &data)

    // if data.IsLocal {
    //     state = false
    // }
    return state
}

func download_all_playlist_of_user(owner_id string, folder string) {
    url := baseURL_playlists + "?limit=50&offset=0"

    httpClient := &http.Client{}
    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("Authorization", "Bearer "+oauthToken)
    res, _ := httpClient.Do(req)

    body, _ := ioutil.ReadAll(res.Body)
    data := new(spotifyPlaylistsOfUser)
    json.Unmarshal(body, &data)
    var counter = 0

    for _,playlist := range data.Items {
        fmt.Printf("Downloading Playlist => %s <=\n",playlist.Name)
        download_playlist_to_folder(playlist.ID,playlist.Owner.ID,folder)
    }
    if data.Total > 50 {
        for(data.Next != nil) {
            nextUrl := *data.Next
            request, _ := http.NewRequest("GET",nextUrl, nil)
            request.Header.Set("Authorization", "Bearer "+oauthToken)
            response, _ := httpClient.Do(request)

            body, _ = ioutil.ReadAll(response.Body)
            json.Unmarshal(body, &data)
            for _,playlist := range data.Items {
                counter++
                fmt.Printf("Downloading Playlist: => %s <=\n",playlist.Name)
                download_playlist_to_folder(playlist.ID,playlist.Owner.ID,folder)
            }
        }
    }
}

func download_playlist_to_folder(playlist_id string, owner_id string, folder string) {
    playlist_name := get_name_of_playlist(playlist_id,owner_id)

    url := baseURL_playlist + playlist_id + "/tracks?limit=100&offset=0"

    httpClient := &http.Client{}
    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("Authorization", "Bearer "+oauthToken)
    res, _ := httpClient.Do(req)

    body, _ := ioutil.ReadAll(res.Body)
    data := new(spotifyPlaylistsTracks)
    json.Unmarshal(body, &data)
    folder = folder + playlist_name+"/"
    var counter = 0

    for _,track := range data.Items {
        counter++
        fmt.Println("Nr: ",counter," | Title: ",track.Track.Name," | Artist: ",track.Track.Artists[0].Name)
        if track.Track.ID == "" {
            // TODO: add file to manual_download list if no spotify id exist
            fmt.Printf("track '%s - %s' is a local file. please download this track manually",track.Track.Artists[0].Name,track.Track.Name)
        } else {
            download_track_to_folder(track.Track.ID,folder)
        }
    }

    if data.Total > 100 {
        for(data.Next != nil) {
            nextUrl := *data.Next
            request, _ := http.NewRequest("GET",nextUrl, nil)
            request.Header.Set("Authorization", "Bearer "+oauthToken)
            response, _ := httpClient.Do(request)

            body, _ = ioutil.ReadAll(response.Body)
            json.Unmarshal(body, &data)
            for _,track := range data.Items {
                counter++
                fmt.Println("Nr: ",counter," | Title: ",track.Track.Name," | Artist: ",track.Track.Artists[0].Name)
                if track.Track.ID == "" {
                    // TODO: add file to manual_download list if no spotify id exist
                    fmt.Printf("track '%s - %s' is a local file. please download this track manually\n",track.Track.Artists[0].Name,track.Track.Name)
                } else {
                    download_track_to_folder(track.Track.ID,folder)
                }
            }
        }
    } 
    fmt.Println("--------------------")
}

func get_name_of_playlist(playlist_id string, owner_id string) (name string) {
    url := baseURL_playlist + playlist_id

    httpClient := &http.Client{}
    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("Authorization", "Bearer "+oauthToken)
    res, _ := httpClient.Do(req)

    body, _ := ioutil.ReadAll(res.Body)
    data := new(spotifyPlaylist)
    json.Unmarshal(body, &data)

    name = data.Name
    return
}

func download_track_to_folder(track_id string, folder string) {
    track_name, artist_name := get_track_and_artist_name(track_id)
    filename := track_name+" - "+artist_name
    youtube_url := search_on_youtube(filename)
    download_mp3_from_youtube(youtube_url,folder,filename)
}

// TODO: return error on failure 
func get_track_and_artist_name(track_id string) (track_name string, artist_name string){
    url := baseURL_track + track_id + "?market=DE"

    httpClient := &http.Client{}
    req, _ := http.NewRequest("GET", url, nil)
    req.Header.Set("Authorization", "Bearer "+oauthToken)
    res, _ := httpClient.Do(req)

    body, _ := ioutil.ReadAll(res.Body)
    data := new(spotifyTrack)
    json.Unmarshal(body, &data)

    return data.Name, data.Artists[0].Name
}

