import os
import json
import requests
import time
import random
import sqlite3
from sqlite3 import Error
from datetime import datetime
from secrets import spotify_user_id, shuffle_source_id, shuffle_target_id
from refresh import Refresh

refreshCaller = Refresh()
count_track = 0
job_done = False

os.system('cls')
print("[•_•] Shuffle - Playlist Shuffler.")
print("Version 2.3.2: 26-FEB-2021 @ 15:09 (c) Viking Design.")
print("See 'about-main.py' and 'about-shuffle.py' for more details.")
print("User: " + spotify_user_id)


class ShuffleFeed:
    def __init__(self):
        self.user_id = spotify_user_id
        self.shuffle_source_playlist_id = shuffle_source_id
        self.shuffle_target_playlist_id = shuffle_target_id
        self.spotify_token = ""
        self.track = ""
        self.getname = ""
        self.here_i_am = os.path.dirname(os.path.abspath(__file__))
        

    def the_business(self):
        tic = time.perf_counter()
        try:
            os.remove(self.here_i_am + "\Playlist Shuffle Tracks - " + spotify_user_id + ".db")
        except:
            pass
        while True:
            self.get_track_from_playlist()
            if job_done:
                toc = time.perf_counter()
                print(f"Shuffle Took {toc - tic:0.2f} Seconds To Complete" )
                return

            self.add_to_db()
            self.remove_track_from_playlist()
        
            

    def check_database(self):                             # NOTE: Create Database and Table If Not Exist
        global database, conn        
        database = self.here_i_am + r"\Playlist Shuffle Tracks - " + spotify_user_id + ".db"
        sql_create_tracks_table = """ CREATE TABLE IF NOT EXISTS tracks (URI text PRIMARY KEY, NAME text); """
        conn = self.create_connection(database)
        if conn is not None:
            self.create_table(conn, sql_create_tracks_table)
        else:
            print("Error! cannot create the database connection.")
                    
    def create_connection(self, db_file):           # NOTE: Create ConnectionTo Database
        conn = None
        try:
            conn = sqlite3.connect(db_file)
            return conn
        except Error as e:
            print(e)
        return conn

    def create_table(self, conn, create_table_sql): # NOTE: Create DAtabase Table
        try:
            c = conn.cursor()
            c.execute(create_table_sql)
            c.close()
        except Error as e:
            print(e)

    def add_to_db(self):                            #NOTE: Add New Track To Database
        global track_id
        database = self.here_i_am + r"\Playlist Shuffle Tracks - " + spotify_user_id + ".db"
        conn = self.create_connection(database)
        with conn:
            tracks = (self.track_uri, self.getname)
            track_id = self.create_track(conn, tracks)

    def create_track(self, conn, trackS):           # NOTE: Insert The Track Into Database
        try:
           sql = ''' INSERT INTO tracks(URI,NAME)
                  VALUES(?,?) '''
           cur = conn.cursor()
           cur.execute(sql, trackS)
           conn.commit()
           return cur.lastrowid
        except:
           return cur.lastrowid
        return

    def get_track_from_playlist(self):
        global row, track_data, job_done
        query = "https://api.spotify.com/v1/playlists/{}/tracks".format(self.shuffle_source_playlist_id)
        response = requests.request("get", url=query, headers={"Content-type": "application/json","Authorization":"Bearer {}".format(self.spotify_token)}, params={"limit":1})
        response_json = response.json()
        json_data = json.loads(response.text)

        try:
            self.track_uri = json_data["items"][0]["track"]["uri"]
            self.track = (json_data["items"][0]["track"]["uri"])[-22:]
            self.getname = json_data["items"][0]["track"]["name"]
            track_data = str(self.track + " - " + self.getname)
        except:
            self.shuffle_tracks_in_database()
            job_done = True
            return
        
        if response.status_code == 200:
            self.check_database()
        return

    def add_track_to_database(self):
        self.remove_track_from_playlist()
        self.shuffle_tracks_in_database()

    def shuffle_tracks_in_database(self):
        database = self.here_i_am + r"\Playlist Shuffle Tracks - " + spotify_user_id + ".db"
    # create a database connection
        conn = self.create_connection(database)
        with conn:
            self.select_all_rows(conn)
        return

    def select_all_rows(self, conn):    
        cur = conn.cursor()
        try:
            cur.execute("SELECT * FROM tracks order by RANDOM()")
        except:
            print("No Tracks In Source Playlist......")
            return
        rows = cur.fetchall()

        for row in rows:
            newtrack = (str(row)[2:38])
            self.add_track_to_playlist(newtrack)

        return
        
    def remove_track_from_playlist(self):
        query = "https://api.spotify.com/v1/playlists/{}/tracks".format(self.shuffle_source_playlist_id)  
        response = requests.request("delete", url=query, headers={"Content-type": "application/json","Authorization":"Bearer {}".format(self.spotify_token)}, data=json.dumps({"tracks": [{"uri": self.track_uri}]}))
        self.track_uri = ""

    def add_track_to_playlist(self, newtrack):
        query = "https://api.spotify.com/v1/playlists/{}/tracks?uris={}".format(self.shuffle_target_playlist_id, newtrack)
        response = requests.request("post", url=query, headers={"Content-type": "application/json","Authorization":"Bearer {}".format(self.spotify_token)})

    def call_refresh(self): #NOTE Euans 2nd Fix
        global refreshCaller
        while True:
            self.spotify_token = refreshCaller.refresh()
            if self.spotify_token == -1:
                now = datetime.now()    
                date_time = now.strftime("%d/%m/%y at %H:%M:%S")
                File_object = open(r"Refresh-Fail-data (DO NOT DELETE!).txt","a")
                File_object.writelines(["Failure at  " + date_time + " - Response code - " + str(response.status_code) + "\n"])
                File_object.close()
 
                print("==============================\n[!] Error refreshing token, retrying in 30 Seconds\n==============================")
                time.sleep(30)
            else:
                break
        
a = ShuffleFeed()
a.call_refresh()
a.the_business()