import time
from functools import total_ordering
from tkinter import *
import threading
import pygame
import requests
from ttkbootstrap import *
import tkinter.messagebox
import tkinter.filedialog
import sys
import re
import os
import json
import subprocess
from random import randint
from random import choice as c
import math
import webbrowser
from pyperclip import copy

# 子代码
from nflmusic import language as lang, make_image, theme_language as tmla, logs, ifm_json as ij
from nflmusic.label_button import LabelButton as lb
from nflmusic import lyrics
from nflmusic.player import MusicPlayer
from nflmusic.load_gif import *


def opening_animation():
    global loaded, appdata
    while True:
        try:
            root0 = Frame(root, height=530, width=810)
            break
        except:
            pass
        time.sleep(0.05)
    root.attributes("-topmost", True)
    root.overrideredirect(True)
    root0.place(x=0, y=0)
    label_image = Label(root0, image=imagetk8)
    label_image.place(relx=0.5, rely=0.5, anchor="center")
    time.sleep(2)
    root0.destroy()
    root.attributes("-topmost", False)
    root.overrideredirect(False)
    homepage_frame.place(x=0, y=0)
    root.config(menu=menubar)
    loaded = True
    run(update)


def make_jsondata():
    appdata = os.getenv("APPDATA")
    with open(appdata + "/.NFLmusic/NFLmusic.json", "w") as f:
        jsondata = ij.usercache
        f.write(json.dumps(jsondata))


def make_lang_json():
    if not os.path.exists(appdata + "/.NFLmusic/language"):
        os.mkdir(appdata + "/.NFLmusic/language")
    with open(appdata + "/.NFLmusic/language/zh_cn.json", "w") as f:
        f.write(json.dumps(ij.Language.zh_cn))
    with open(appdata + "/.NFLmusic/language/en_us.json", "w") as f:
        f.write(json.dumps(ij.Language.en_us))


def save_jsondata():
    jsondata["language"] = var5.get()
    jsondata["choice"] = repo_dict[var4.get()]
    jsondata["auto_update"] = var3.get()
    jsondata["auto_play"] = var6.get()
    tm = var1.get()
    style.theme = tmla.get(la)[tm]
    jsondata["theme"] = tmla.get(la)[tm]
    if not os.path.exists(var2.get()):
        var2.set(path)
    jsondata["path"] = var2.get()
    with open(appdata + "/.NFLmusic/NFLmusic.json", "w") as f:
        f.write(json.dumps(jsondata))


def detect_change():
    global changed
    if (
        jsondata["language"] != var5.get() or
        jsondata["choice"] != repo_dict[var4.get()] or
        jsondata["auto_update"] != var3.get() or
        jsondata["auto_play"] != var6.get() or
        jsondata["theme"] != tmla.get(la)[var1.get()] or
        jsondata["path"] != var2.get()
    ):
        changed = True



def display(window, msg, ltime=3):
    a = Label(window, text=msg)
    a.place(relx=0.5, rely=0.9, anchor="center")
    time.sleep(ltime)
    a.destroy()


def get_treeview_index(tree, item):
    parent_id = tree.parent(item)
    if parent_id:
        # 如果有父节点，获取父节点下所有子节点，并返回目标节点在其中的索引值
        children = tree.get_children(parent_id)
        return children.index(item)
    else:
        # 如果没有父节点，直接返回根节点下的索引值
        root_children = tree.get_children()
        return root_children.index(item)


def download_check(*value):
    global downloading
    time.sleep(0.2)
    try:
        if not downloading:
            downloading = True
            run(download_music, var0.get(), get_treeview_index(songlist, songlist.selection()[0]) + 1)
    except:
        downloading = False


def download_music(song_name, choose):
    global progressbar, downloading

    def update_progressbar():
        while True:
            progress = int((downloaded / total_length) * 100)
            progressbar['value'] = progress
            if downloaded == total_length:
                break
            time.sleep(0.05)

    try:
        progressbar = Progressbar(labelframe_download, mode='determinate', length=490,
                                  style='success.Striped.Horizontal.TProgressbar')
        progressbar.place(x=10, y=300)
        br = br_dict[var.get()]
        if choice == "KUWO":
            resp = requests.get(f"{url}?msg={song_name}&n={choose}&br={br}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3")
            resp.close()
            id = resp.json()["link"].rsplit("/", 1)[1]
            try:
                resp_lrc = requests.get(f"http://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId={id}")
                resp_lrc.close()
                lrc = ""
                lrclist = resp_lrc.json()["data"]["lrclist"]
                for i in lrclist:
                    total_time = i["time"]
                    min = float(total_time) // 60
                    sec = float(total_time) % 60
                    lrc += f'[{int(min)}:{sec}]{i["lineLyric"]}\n'
            except Exception as e:
                print(f"download_kw_lrc: {e}")
                lrc = ""
            music_name = resp.json()["song_name"]
            singer = resp.json()["song_singer"]
            music_url = resp.json()["flac_url"]
        elif choice == "WANGYIYUN":
            resp = requests.get(f"{url}?gm={song_name}&n={choose}&br={br}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3")
            resp.close()
            id = resp.json()["link"].rsplit("=", 1)[1]
            try:
                resp_lrc = requests.get(f"https://music.163.com/api/song/lyric?id={id}&lv=-1&kv=-1&tv=-1")
                resp_lrc.close()
                lrc = resp_lrc.json()["lrc"]["lyric"]
            except Exception as e:
                print(f"download_wyy_lrc: {e}")
                lrc = ""
            music_name = resp.json()["title"]
            singer = resp.json()["singer"]
            music_url = resp.json()["music_url"]
        elif choice == "QQ":
            resp = requests.get(f"{url}?msg={song_name}&n={choose}&num=60&type=json&br={br}&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3")
            resp.close()
            try:
                lrc = resp.json()["data"]["lyric"]
            except Exception as e:
                print(f"download_qq_lrc: {e}")
                lrc = ""
            music_name = resp.json()["data"]["song_name"]
            singer = resp.json()["data"]["song_singer"]
            music_url = resp.json()["data"]["music_url"]
        elif choice == "KUGOU":
            song_name = song_name.replace(" ", "")
            resp = requests.get(f"{url}?msg={song_name}&n={choose}&num=60&type=json&br={br}&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3")
            resp.close()
            try:
                lrc = resp.json()["lyrics"]
            except Exception as e:
                print(f"download_kg_lrc: {e}")
                lrc = ""
            music_name = resp.json()["title"]
            singer = resp.json()["singer"]
            music_url = resp.json()["music_url"]
        elif choice == "JUHE":
            song_name = song_name.replace(" ", "")
            resp = requests.get(f"{url}?msg={song_name}&n={choose}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3")
            resp.close()
            try:
                lrc = resp.json()["data"]["lyric"]
                print(lrc)
                # 正则表达式匹配 [mm:ss]
                def convert_timestamp(match):
                    mm_ss = match.group(1)
                    minutes, seconds = mm_ss.split(':')
                    # 转换为浮点秒数并保留一位小数（虽然这里是整数）
                    total_seconds = int(minutes) * 60 + int(seconds)
                    # 格式化回 mm:ss.s 形式
                    new_minutes = total_seconds // 60
                    new_seconds = total_seconds % 60
                    return f"[{new_minutes:02d}:{new_seconds:02d}.0]"

                # 替换所有 [mm:ss] 为 [mm:ss.0]
                lrc = re.sub(r'\[(\d{2}:\d{2})\]', convert_timestamp, lrc)
            except Exception as e:
                print(f"download_kg_lrc: {e}")
                lrc = ""
            music_name = resp.json()["data"]["title"]
            singer = resp.json()["data"]["singer"]
            music_url = resp.json()["data"]["url"]
        else:
            lrc = ""
        lrc = lrc.replace("\\n", "\n")
        print("请求api:", url)
        response = requests.get(music_url, stream=True)
        print("下载直链:", music_url)
        formated = music_url.split("?")[0].rsplit(".", 1)[1]
        if formated not in ["m4a", "mp3", "ogg", "flac"]:
            formated = "mp3"
        filename_without_endswith = f"{singer} - {music_name}"
        filename_without_endswith = filename_without_endswith.replace("\\", "#").replace("/", "#")
        filename_without_endswith = filename_without_endswith.replace(":", "#").replace("*", "#")
        filename_without_endswith = filename_without_endswith.replace("?", "#").replace("\"", "#")
        filename_without_endswith = filename_without_endswith.replace("<", "#").replace(">", "#").replace("|", "#")

        filename = f"{filename_without_endswith}.{formated}"
        temp_filename = f"{filename}.crdownload"

        if path == "./music":
            if os.path.exists("./music"):
                pass
            else:
                os.makedirs("./music")

        try:
            if lrc:
                with open(os.path.join(path, f"{filename_without_endswith}.lrc", ), "w", encoding="utf-8") as f:
                    f.write(lrc)
        except:
            pass

        temp_filepath = os.path.join(path, temp_filename)
        final_filepath = os.path.join(path, filename)

        # 检查同名文件是否存在
        if os.path.exists(final_filepath):
            progressbar.destroy()
            response.close()
            if not lrc:
                display(labelframe_download, lang.get(la, 'ui.download.text.file_exists', {"_filename_": filename}))
            else:
                display(labelframe_download, lang.get(la, 'ui.download.text.download_lyrics_success'))
            downloading = False
            return

        with open(temp_filepath, "wb") as f:
            total_length = int(response.headers.get('content-length'))
            downloaded = 0
            run(update_progressbar)
            for data in response.iter_content(chunk_size=1024):
                downloaded += len(data)
                f.write(data)

        os.rename(temp_filepath, final_filepath)

        refresh()
        time.sleep(0.1)
        progressbar.destroy()
        response.close()
        display(labelframe_download, lang.get(la, 'ui.download.text.download_success',
                                              {"_singer_": f"{singer}", "_music_": f"{music_name}"}))
        downloading = False

    except KeyError:
        downloading = False
        progressbar.destroy()
        if song_name == "":
            songlist.delete(0, "end")
            display(labelframe_download, lang.get(la, "ui.download.text.download_fail_no_keys"))
        else:
            display(labelframe_download, lang.get(la, "ui.download.text.search_fail_not_found"))
    except PermissionError:
        downloading = False
        progressbar.destroy()
        response.close()
        display(labelframe_download, lang.get(la, "ui.download.text.download_fail_no_permission"))
    except requests.exceptions.ConnectionError:
        downloading = False
        progressbar.destroy()
        response.close()
        display(labelframe_download, lang.get(la, "ui.download.text.download_fail_no_network"))
    except FileNotFoundError:
        downloading = False
        progressbar.destroy()
        response.close()
        display(labelframe_download, lang.get(la, "ui.download.text.download_fail_file_not_found"))
    except FileExistsError:
        downloading = False
        progressbar.destroy()
        response.close()
        display(labelframe_download, lang.get(la, 'ui.download.text.download_success',
                                              {"_singer_": f"{singer}", "_music_": f"{music_name}"}))


def run(task, *args):
    t = threading.Thread(target=task, args=args, daemon=True)
    t.start()


def get_data_without_blocking(song_name):
    def search_and_update_list():
        global last_search_target
        if song_name != last_search_target:
            try:
                button0["state"] = "disabled"
                songlist.delete(*songlist.get_children())
                if choice == "KUWO":
                    url1 = f"{url}?msg={song_name}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3"
                elif choice == "WANGYIYUN":
                    url1 = f"{url}?gm={song_name}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3"
                elif choice == "QQ":
                    url1 = f"{url}?msg={song_name}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3"
                elif choice == "KUGOU":
                    url1 = f"{url}?msg={song_name.replace(' ', '')}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3"
                elif choice == "JUHE":
                    url1 = f"{url}?msg={song_name}&num=60&type=json&key=Dragon5B887C2DC41AD03C93F06BAF4B7888C3"
                resp = requests.get(url1)
                jsondata = resp.json()
                resp.close()
                last_search_target = song_name
                for index in range(len(jsondata["data"] if isinstance(jsondata, dict) else jsondata)):
                    if choice == "KUWO":
                        full_name = jsondata["data"][index]["songname"]
                        artist = jsondata["data"][index]["singer"]
                        album = jsondata["data"][index]["song_rid"]
                    elif choice == "WANGYIYUN":
                        full_name = jsondata["data"][index]["title"]
                        artist = jsondata["data"][index]["singer"]
                        album = jsondata["data"][index]["songid"]
                    elif choice == "QQ":
                        full_name = jsondata["data"][index]["song_title"]
                        artist = jsondata["data"][index]["song_singer"]
                        album = ""
                    elif choice == "KUGOU":
                        full_name = jsondata["data"][index]["title"]
                        artist = jsondata["data"][index]["singer"]
                        album = ""
                    elif choice == "JUHE":
                        full_name = jsondata[index]["title"]
                        artist = jsondata[index]["singer"]
                        album = jsondata[index]["app"]
                    songlist.insert("", "end", values=(full_name, artist, album))
            except requests.exceptions.JSONDecodeError:
                resp_text = resp.text
                songname_rule = '"songname": "(.*?)",'
                name_rule = '"name": "(.*?)",'
                songname_list = re.findall(songname_rule, resp_text)
                name_list = re.findall(name_rule, resp_text)
                for index in range(len(songname_list) - 1):
                    full_name = songname_list[index]
                    artist = name_list[index]
                    songlist.insert("", "end", values=(full_name, artist))
            except TypeError:
                pass
            except:
                tkinter.messagebox.showinfo(title=lang.get(la, "mbox.title.search_fail"),
                                            message=lang.get(la, "mbox.text.search_fail", ))
                pass
            finally:
                button0["state"] = "normal"

    search_thread = threading.Thread(target=search_and_update_list)
    search_thread.start()


def refresh():
    global music_dir, music_dir_without_endswith
    try:
        listbox1.delete(0, "end")
        music_dir_without_endswith = [os.path.splitext(file)[0] for file in os.listdir(path) if
                                      file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
        music_dir = [file for file in os.listdir(path) if file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
        if var7.get() in ["", lang.get(la, "ui.download.entry.song_name")]:
            for musics in music_dir_without_endswith:
                listbox1.insert(END, musics)
        else:
            for musics in music_dir_without_endswith:
                if var7.get() in musics:
                    listbox1.insert(END, musics)
    except:
        pass


def delete():
    global listbox1, filtered_list, music_dir, music_dir_without_endswith
    try:
        if tkinter.messagebox.askokcancel(lang.get(la, "mbox.title.delete"), lang.get(la, "mbox.text.delete", )):
            abs_path = path + "/" + music_dir[listbox1.curselection()[0]]
            abs_path_lrc = path + "/" + music_dir_without_endswith[listbox1.curselection()[0]] + ".lrc"
            if var7.get() not in ["", lang.get(la, "ui.download.entry.song_name")]:
                music_dir_filtered = []
                for file in music_dir:
                    if var7.get() in os.path.splitext(file)[0]:
                        music_dir_filtered.append(file)
                music_dir0 = music_dir_filtered
                music_dir_without_endswith0 = [os.path.splitext(file)[0] for file in music_dir0 if
                                              file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
                abs_path = path + "/" + music_dir0[listbox1.curselection()[0]]
                abs_path_lrc = path + "/" + music_dir_without_endswith0[listbox1.curselection()[0]] + ".lrc"
            os.remove(abs_path)
            try:
                os.remove(abs_path_lrc)
            except:
                pass
            music_dir_without_endswith.remove(listbox1.get(0, END)[listbox1.curselection()[0]])
            music_dir.remove(music_dir[listbox1.curselection()[0]])
            listbox1.delete(listbox1.curselection()[0])
    except IndexError:
        tkinter.messagebox.showwarning(title=lang.get(la, "mbox.title.delete_fail"),
                                       message=lang.get(la, "mbox.text.delete_fail_no_target", ))
    except PermissionError:
        try:
            stopmusic()
            os.remove(abs_path)
            try:
                os.remove(abs_path_lrc)
            except:
                pass
            music_dir_without_endswith.remove(listbox1.get(0, END)[listbox1.curselection()[0]])
            del music_dir[listbox1.curselection()[0]]
            listbox1.delete(listbox1.curselection()[0])
        except Exception as e:
            print(e, type(e))
            tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.delete_fail"),
                                     message=lang.get(la, "mbox.text.delete_fail_no_permission", ))
    except FileNotFoundError:
        tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.delete_fail"),
                                     message=lang.get(la, "mbox.text.delete_fail_not_found", ))


def pausesound():
    global music_dir, player
    try:
        if not music_player.get_finished():
            music_player.pause_music()
    except IndexError:
        tkinter.messagebox.showwarning(title=lang.get(la, "mbox.title.play_fail"),
                                       message=lang.get(la, "mbox.text.play_fail_no_target", ))
    except:
        pass
        tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.play_fail"),
                                     message=lang.get(la, "mbox.text.play_fail_not_found", ))


def playsound(*event):
    global music_playing, music_file_name, music_file_without_endswith, lyric, song_list, song_list_limit, music_dir
    if not music_player.get_finished():
        music_player.stop_music()
    lyric = ""
    music_dir_without_endswith = [os.path.splitext(file)[0] for file in os.listdir(path) if
                                  file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
    music_dir = [file for file in os.listdir(path) if file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
    if var7.get() not in ["", lang.get(la, "ui.download.entry.song_name")]:
        music_dir_filtered = []
        for file in music_dir:
            if var7.get() in os.path.splitext(file)[0]:
                music_dir_filtered.append(file)
        music_dir = music_dir_filtered
        music_dir_without_endswith = [os.path.splitext(file)[0] for file in music_dir if
                                  file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
    abs_path = path + "/" + music_dir[listbox1.curselection()[0]]
    if abs_path not in song_list:
        song_list.append(abs_path)
        if len(song_list) > song_list_limit:
            del song_list[0]
    music_playing = abs_path
    music_file_name = music_dir[listbox1.curselection()[0]]
    music_file_without_endswith = music_dir_without_endswith[listbox1.curselection()[0]]
    music_player.set_format_of_time(
        lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
    playmusic(abs_path)
    try:
        lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
    except Exception as e:
        print(type(e), e)


def playmusic(music_path):
    music_name = music_path.split("/")[-1]
    try:
        music_player.stop_music()
    except:
        pass
    try:
        music_player.play_music(music_path)
    except pygame.error:
        os.startfile(music_path)
    except:
        pass


def stopmusic():
    global music_playing
    music_playing = ""
    music_player.stop_music()


def restart0():
    root.destroy()
    python = sys.executable
    os.execl(python, python, *sys.argv)


def save_sth():
    jsondata["br"][choice] = var.get()
    jsondata["playing_mode"] = playingmode
    save_jsondata()
    root.destroy()


def display_sentences():
    global poem, passage, label0
    time.sleep(0.1)
    poem = ""
    try:
        resp = requests.get("http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/random_quote")
        poem = resp.text.replace("\r", "").split("\n")
        resp.close()
        resp0 = requests.get("http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/announcement")
        announcement_text = resp0.text.replace("\\n", "")
        resp0.close()
        poem = c(poem)
        poem_lines = [poem[i:i + 15] for i in range(0, len(poem), 15)]
        passage = lang.get(la, "ui.about.text.information", {"_version_": version})
        time.sleep(2)
        random_quote["text"] = "\n".join(poem_lines)
        announcement["text"] = lang.get(la, "ui.about.text.announcement", {"_announcement_": announcement_text})
        label0["text"] = passage
    except requests.exceptions.ConnectionError:
        poem = c(lang.get(la, "ui.about.text.starting_poem", ))
        poem_lines = [poem[i:i + 15] for i in range(0, len(poem), 15)]
        passage = lang.get(la, "ui.about.text.information", {"_version_": version})
        while True:
            if loaded:
                break
            time.sleep(0.05)
        tkinter.messagebox.showinfo(title=lang.get(la, "mbox.title.network_connection_fail"),
                                    message=lang.get(la, "mbox.text.network_connection_fail", ))
        random_quote["text"] = "\n".join(poem_lines)
        label0["text"] = passage


def make_resource():
    global resource_path
    resource_path = os.getenv('APPDATA')
    make_image.get(resource_path)


def open_file_dialog():
    filepath = tkinter.filedialog.askdirectory()
    if filepath:
        var2.set(filepath)


def settings():
    global page, changed
    detect_change()
    if changed:
        response = tkinter.messagebox.askyesnocancel(lang.get(la, "mbox.title.save_settings"),
                                                     lang.get(la, "mbox.text.save_settings", ))
        if response is not None:
            if response:
                if not os.path.exists(var2.get()):
                    tkinter.messagebox.showwarning(title=lang.get(la, "mbox.title.position_not_exist"),
                                                   message=lang.get(la, "mbox.text.position_not_exist", ))
                else:
                    jsondata["br"][choice] = var.get()
                    jsondata["playing_mode"] = playingmode
                    save_jsondata()
                    tkinter.messagebox.showinfo(message=lang.get(la, "mbox.text.restart"),
                                                title=lang.get(la, "mbox.title.restart", ))
                    restart0()
            else:
                page = will_page
                if page == "homepage":
                    ExchangeGUI.home_page()
                elif page == "about":
                    ExchangeGUI.about()
                elif page == "versions":
                    ExchangeGUI.versions()
                var1.set(tmla.catch(la, jsondata["theme"]))
                var2.set(path)
                var3.set(auto_update)
                var4.set(repo_dict_reverse[choice])
                var5.set(la)
                var6.set(auto_play)
        else:
            pass
    else:
        page = will_page
        if page == "homepage":
            ExchangeGUI.home_page()
        elif page == "about":
            ExchangeGUI.about()
        elif page == "versions":
            ExchangeGUI.versions()
    changed = False


class joke:
    @staticmethod
    def parabola_frame():
        x = -400
        while True:
            y = pow(x / 10, 2)
            root.geometry(f'+{x + 400}+{int(y)}')
            time.sleep(0.01)
            x += 1
            if x == 400:
                x = -400

    @staticmethod
    def jump_window():
        while True:
            for x in range(0, 20):
                y = pow(x, 2)
                root.geometry(f'+0+{int(y)}')
                time.sleep(0.02)
            for x in range(0, 20):
                y = pow(19 - x, 2)
                root.geometry(f'+0+{int(y)}')
                time.sleep(0.02)

    @staticmethod
    def wave_window():
        while True:
            for x in range(-1080, 1440):
                y = math.sin(x / 180 * math.pi)
                root.geometry(f'+{int(x)}+{int(y * 300) + 300}')
                time.sleep(0.01)

    @staticmethod
    def portal_window():
        while True:
            root.geometry(f'+{randint(0, 400)}+{randint(0, 400)}')
            time.sleep(0.1)

    @staticmethod
    def repeat_window():
        for i in range(10):
            run(tkinter.messagebox.showinfo, lang.get(la, "mbox.title.joke0"), lang.get(la, "mbox.text.joke0", ))

    @staticmethod
    def circle_window():
        while True:
            for i in range(360):
                x = math.cos(i / 180 * math.pi)
                y = math.sin(i / 180 * math.pi)
                root.geometry(f'{int(x * 300) + 400}x{int(y * 300) + 300}+{int(x * 300) + 400}+{int(y * 300) + 300}')
                time.sleep(0.01)


def do_not_click():
    global isJoking
    if not isJoking:
        tkinter.messagebox.showwarning(lang.get(la, "mbox.title.joke_warning"),
                                       lang.get(la, "mbox.text.joke_warning", ))
        joke_mode = randint(0, 5)
        ExchangeGUI.home_page()
        isJoking = True
        if joke_mode == 0:
            run(joke.wave_window)
        elif joke_mode == 1:
            run(joke.jump_window)
        elif joke_mode == 2:
            run(joke.parabola_frame)
        elif joke_mode == 3:
            run(joke.repeat_window)
            isJoking = False
        elif joke_mode == 4:
            run(joke.portal_window)
        elif joke_mode == 5:
            run(joke.circle_window)
    else:
        tkinter.messagebox.showwarning(lang.get(la, "mbox.title.joke_fail"),
                                       lang.get(la, "mbox.text.joke_fail", ))


def update():
    global datalist, have_checked, screen_height, screen_width

    def f_update_progressbar():
        while True:
            progress = int((downloaded / total_length) * 100)
            update_progressbar['value'] = progress
            if downloaded == total_length:
                break
            time.sleep(0.05)

    def f_app_progressbar():
        while True:
            progress = int((downloaded / total_length) * 100)
            app_progressbar['value'] = progress
            if downloaded == total_length:
                break
            time.sleep(0.05)

    def prevent_closing():
        pass

    def run_update():
        subprocess.Popen(update_path + "update.exe")

    appdata = os.getenv('APPDATA')
    if not os.path.exists(appdata + "/.NFLmusic/update"):
        os.mkdir(appdata + "/.NFLmusic/update")
    if not have_checked:
        data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/data"
        data_resp = requests.get(data_url)
        data_resp.close()
        datalist = data_resp.text.replace("\r", "").split("\n")
    update_path = appdata + "/.NFLmusic/update/"
    data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/latest_update_log"
    data_resp = requests.get(data_url).text
    latest_version = datalist[0]
    if latest_version != version:
        if not jsondata["auto_update"]:
            response = tkinter.messagebox.askquestion(
                lang.get(la, "mbox.title.update_reminding", {"_version_": latest_version}),
                lang.get(la, "mbox.text.update_reminding", {"_update_": data_resp}))
            if response == "yes":
                check_update_button["state"] = "disabled"
                # 将root隐藏
                root.withdraw()
                download_page = Toplevel(root)
                x_dl = (screen_width - 360) // 2
                y_dl = (screen_height - 200) // 2
                download_page.geometry(f"360x200+{x_dl}+{y_dl}")
                download_page.title(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}))
                download_page.protocol("WM_DELETE_WINDOW", prevent_closing)
                download_page.resizable(False, False)
                download_page.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")
                update_progressbar = Progressbar(download_page, mode="determinate", length=320,
                                                 style="success.Striped.Horizontal.TProgressbar")
                app_progressbar = Progressbar(download_page, mode="determinate", length=320,
                                              style="info.Striped.Horizontal.TProgressbar")
                Label(download_page, text=lang.get(la, "ui.update.text.download_update")).pack()
                update_progressbar.pack()
                Label(download_page, text=f"\n\n{lang.get(la, 'ui.update.text.download_app')}").pack()
                app_progressbar.pack()
                update_url = datalist[1]
                app_url = datalist[2]
                try:
                    update_resp = requests.get(update_url, stream=True)
                    app_resp = requests.get(app_url, stream=True)
                    with open(update_path + "file_path", "w") as f:
                        f.write(latest_version + "\n" + os.path.abspath(sys.executable))
                    with open(update_path + "update.exe", "wb") as f:
                        total_length = int(update_resp.headers.get('content-length'))
                        downloaded = 0
                        run(f_update_progressbar)
                        for data in update_resp.iter_content(chunk_size=1024):
                            downloaded += len(data)
                            f.write(data)
                    time.sleep(0.1)
                    with open(update_path + f"NFLmusicv{latest_version}.exe", "wb") as f:
                        total_length = int(app_resp.headers.get('content-length'))
                        downloaded = 0
                        run(f_app_progressbar)
                        for data in app_resp.iter_content(chunk_size=1024):
                            downloaded += len(data)
                            f.write(data)
                    run_update()
                    download_page.destroy()
                    root.destroy()
                except Exception as e:
                    # 重新显示窗口
                    check_update_button["state"] = "normal"
                    root.deiconify()
                    print(e)
                    download_page.destroy()
                    tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.update_fail"),
                                                 message=lang.get(la, "mbox.text.update_fail", ))
            else:
                check_update_button["state"] = "normal"
        else:
            tkinter.messagebox.showinfo(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}),
                                        lang.get(la, "mbox.text.update_start_auto", {"_update_": data_resp}))
            check_update_button["state"] = "disabled"
            # 将root隐藏
            root.withdraw()
            download_page = Toplevel(root)
            x_dl = (screen_width - 360) // 2
            y_dl = (screen_height - 200) // 2
            download_page.geometry(f"360x200+{x_dl}+{y_dl}")
            download_page.title(lang.get(la, "mbox.title.update_start", {"_version_": latest_version}))
            download_page.protocol("WM_DELETE_WINDOW", prevent_closing)
            download_page.resizable(False, False)
            download_page.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")
            update_progressbar = Progressbar(download_page, mode="determinate", length=320,
                                             style="success.Striped.Horizontal.TProgressbar")
            app_progressbar = Progressbar(download_page, mode="determinate", length=320,
                                          style="info.Striped.Horizontal.TProgressbar")
            Label(download_page, text=lang.get(la, "ui.update.text.download_update")).pack()
            update_progressbar.pack()
            Label(download_page, text=f"\n\n{lang.get(la, 'ui.update.text.download_app')}").pack()
            app_progressbar.pack()
            update_url = datalist[1]
            app_url = datalist[2]
            try:
                update_resp = requests.get(update_url, stream=True)
                app_resp = requests.get(app_url, stream=True)
                with open(update_path + "file_path", "w") as f:
                    f.write(latest_version + "\n" + os.path.abspath(sys.executable))
                with open(update_path + "update.exe", "wb") as f:
                    total_length = int(update_resp.headers.get('content-length'))
                    downloaded = 0
                    run(f_update_progressbar)
                    for data in update_resp.iter_content(chunk_size=1024):
                        downloaded += len(data)
                        f.write(data)
                time.sleep(0.1)
                with open(update_path + f"NFLmusicv{latest_version}.exe", "wb") as f:
                    total_length = int(app_resp.headers.get('content-length'))
                    downloaded = 0
                    run(f_app_progressbar)
                    for data in app_resp.iter_content(chunk_size=1024):
                        downloaded += len(data)
                        f.write(data)
                run_update()
                download_page.destroy()
                root.destroy()
            except Exception as e:
                # 重新显示窗口
                check_update_button["state"] = "normal"
                root.deiconify()
                print(e)
                download_page.destroy()
                tkinter.messagebox.showerror(title=lang.get(la, "mbox.title.update_fail"),
                                             message=lang.get(la, "mbox.text.update_fail", ))


def check_update():
    global datalist, have_checked
    check_update_button["state"] = "disabled"
    try:
        data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/data"
        data_resp = requests.get(data_url)
        datalist = data_resp.text.replace("\r", "").split("\n")
        latest_version = datalist[0]
        data_resp.close()
        if version == latest_version:
            tkinter.messagebox.showinfo(lang.get(la, "mbox.title.update_reminding", {"- v_version_": ""}),
                                        lang.get(la, "mbox.text.update_latest"))
            check_update_button["state"] = "normal"
        else:
            run(update)
    except:
        check_update_button["state"] = "normal"
    have_checked = True


class ExchangeGUI:
    exchanged = False
    page_list = ["homepage", "settings", "about", "versions"]

    @staticmethod
    def close_other_page():
        homepage_frame.place_forget()
        setting_frame.place_forget()
        about_frame.place_forget()
        version_frame.place_forget()

    @classmethod
    def display_animation(cls, frame, current_page):
        if not cls.exchanged:
            global page
            cls.exchanged = True
            frame.place(x=0, y=1000)

            def animation():
                global page, former_page
                if cls.page_list.index(page) > cls.page_list.index(former_page):
                    for i in range(40, 0, -1):
                        frame.place(x=pow(i, 2), y=0)
                        time.sleep(0.01)
                elif cls.page_list.index(page) < cls.page_list.index(former_page):
                    for i in range(40, 0, -1):
                        frame.place(x=-pow(i, 2), y=0)
                        time.sleep(0.01)
                elif cls.page_list.index(page) == cls.page_list.index(former_page):
                    for i in range(40, 0, -1):
                        frame.place(x=0, y=pow(i, 2))
                        time.sleep(0.01)
                cls.exchanged = False
                page = current_page

            run(animation)

    @staticmethod
    def home_page():
        global page, will_page, former_page
        if page == "settings":
            will_page = "homepage"
            settings()
        else:
            ExchangeGUI.close_other_page()
            page = "homepage"
            ExchangeGUI.display_animation(homepage_frame, page)
        former_page = "homepage"

    @staticmethod
    def window_settings():
        global page, former_page
        ExchangeGUI.close_other_page()
        var2.set(path)
        page = "settings"
        ExchangeGUI.display_animation(setting_frame, page)
        former_page = "settings"

    @staticmethod
    def about():
        global page, will_page, former_page
        will_page = "about"
        if page == "settings":
            will_page = "about"
            settings()
        else:
            ExchangeGUI.close_other_page()
            page = "about"
            ExchangeGUI.display_animation(about_frame, page)
        former_page = "about"

    @staticmethod
    def versions():
        global page, will_page, former_page
        will_page = "versions"
        if page == "settings":
            will_page = "versions"
            settings()
        else:
            ExchangeGUI.close_other_page()
            page = "versions"
            ExchangeGUI.display_animation(version_frame, page)
        former_page = "versions"


def tick():
    def lrc_rolling(timestamp):
        global next_showed
        try:
            lrc = lyrics.get_lyrics(lyric, music_player.get_progress())
            try:
                timestamp_list = list(lyric.keys())
                next_timestamp = timestamp_list[timestamp_list.index(timestamp) + 1]
                this_time = music_player.decode_format(timestamp)
                next_time = music_player.decode_format(next_timestamp)
                rolling_frequency = (next_time - this_time) / (len(lrc) - 30) / 1.5
            except:
                end_time = music_player.decode_format(music_player.get_length())
                this_time = music_player.decode_format(timestamp)
                rolling_frequency = (end_time - this_time) / (len(lrc) - 30) / 1.5
            for i in range(0, len(lrc) - 30):
                music_lrc["text"] = lrc[i:i + 31]
                time.sleep(rolling_frequency)
                if next_showed:
                    next_showed = False
                    break
        except:
            pass

    global music_playing, playingmode, music_file_name, music_file_without_endswith, lyric, song_list
    last_timestamp = "0"
    while True:
        try:
            music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
                                   file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
            song_list = [song for song in song_list if song in music_dir_with_path]
            if music_player.finish:
                if auto_play:
                    playing_progress.state(["disabled"])
                    playsoundButton["image"] = imagetk1
                    try:
                        if playingmode == 0:
                            if music_playing:
                                refresh()
                                music_player.set_format_of_time(
                                    lang.get(la, "ui.playing.text.time_format",
                                             {"_music_": music_file_without_endswith}))
                                playmusic(music_playing)
                        if playingmode == 1:
                            if music_playing:
                                refresh()
                                music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
                                                       file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
                                if music_playing == song_list[-1]:
                                    if len(song_list) >= len(music_dir_with_path):
                                        del song_list[0]
                                    elif len(song_list) > song_list_limit:
                                        del song_list[0]
                                    song_list_full = [song for song in music_dir_with_path if song not in song_list]
                                    random_index = randint(0, len(song_list_full) - 1)
                                    abs_path = song_list_full[random_index]
                                    music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
                                    song_list.append(abs_path)
                                    music_playing = abs_path
                                else:
                                    try:
                                        current_index = song_list.index(music_playing)
                                    except ValueError:
                                        current_index = -1
                                    abs_path = song_list[current_index + 1]
                                    music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
                                    music_playing = abs_path
                                try:
                                    lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
                                except Exception as e:
                                    print("lyric: ", e)
                                    lyric = {}
                                music_player.set_format_of_time(
                                    lang.get(la, "ui.playing.text.time_format",
                                             {"_music_": music_file_without_endswith}))
                                playmusic(abs_path)
                        if playingmode == 2:
                            if music_playing:
                                refresh()
                                music_dir = [file for file in os.listdir(path) if
                                             file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
                                music_dir_without_endswith = [os.path.splitext(file)[0] for file in os.listdir(path) if
                                                              file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
                                try:
                                    music_file_name = music_dir[music_dir.index(music_file_name) + 1]
                                    music_file_without_endswith = music_dir_without_endswith[
                                        music_dir_without_endswith.index(music_file_without_endswith) + 1]
                                    abs_path = path + "/" + music_file_name
                                    music_playing = abs_path
                                    try:
                                        lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
                                    except Exception as e:
                                        print("lyric: ", e)
                                        lyric = {}
                                except IndexError:
                                    music_file_name = music_dir[0]
                                    music_file_without_endswith = music_dir_without_endswith[0]
                                    music_playing = path + "/" + music_file_name
                                    try:
                                        lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
                                    except:
                                        lyric = {}
                                music_player.set_format_of_time(
                                    lang.get(la, "ui.playing.text.time_format",
                                             {"_music_": music_file_without_endswith}))
                                playmusic(music_playing)
                    except Exception as e:
                        print("External loop error: ", e)
                        pass
            else:
                playing_progress.state(["!disabled"])
                try:
                    if lyric:
                        if len(lyrics.get_lyrics(lyric, music_player.get_progress())) >= 30:
                            if last_timestamp != music_player.get_progress():
                                run(lrc_rolling, music_player.get_progress())
                                last_timestamp = music_player.get_progress()
                        else:
                            next_showed = True
                            music_lrc["text"] = lyrics.get_lyrics(lyric, music_player.get_progress())
                    else:
                        music_lrc["text"] = ""
                except:
                    pass
            if music_player.get_busy():
                playsoundButton["image"] = imagetk6
            else:
                playsoundButton["image"] = imagetk1
        except:
            pass
        time.sleep(0.1)


def former_song():
    global music_playing, lyric, music_file_name, song_list, song_list_limit, music_file_without_endswith
    if playingmode == 1:
        refresh()
        music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
                               file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
        if music_playing == song_list[0]:
            if len(song_list) >= len(music_dir_with_path):
                del song_list[-1]
            elif len(song_list) > song_list_limit:
                del song_list[-1]
            song_list_full = [song for song in music_dir_with_path if song not in song_list]
            random_index = randint(0, len(song_list_full) - 1)
            abs_path = song_list_full[random_index]
            music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
            song_list.insert(0, abs_path)
            music_playing = abs_path
        else:
            try:
                current_index = song_list.index(music_playing)
            except ValueError:
                song_list.append(music_playing)
                current_index = -1
            abs_path = song_list[current_index - 1]
            music_file_without_endswith = abs_path.rsplit("/")[-1].rsplit(".", 1)[0]
            music_playing = abs_path
        try:
            lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
        except:
            lyric = {}
        music_player.set_format_of_time(
            lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
        playmusic(abs_path)
    if playingmode in [0, 2]:
        refresh()
        music_dir = [file for file in os.listdir(path) if
                     file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
        try:
            music_file_name = music_dir[music_dir.index(music_playing.split("/")[-1]) - 1]
            music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
            abs_path = path + "/" + music_file_name
            music_playing = abs_path
            try:
                lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
            except:
                lyric = {}
        except IndexError:
            music_file_name = music_dir[0]
            music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
            music_playing = path + "/" + music_file_name
            try:
                lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
            except:
                lyric = {}
        music_player.set_format_of_time(
            lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
        playmusic(music_playing)


def latter_song():
    global music_playing, lyric, music_file_name, song_list, song_list_limit, music_file_without_endswith
    if playingmode == 1:
        refresh()
        music_dir_with_path = [path + "/" + file for file in os.listdir(path) if
                               file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
        try:
            last_song = song_list[-1]
        except IndexError:
            last_song = song_list[0]
        if music_playing == last_song:
            if len(song_list) >= len(music_dir_with_path):
                del song_list[0]
            elif len(song_list) > song_list_limit:
                del song_list[0]
            song_list_full = [song for song in music_dir_with_path if song not in song_list]
            random_index = randint(0, len(song_list_full) - 1)
            abs_path = song_list_full[random_index]
            music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
            song_list.append(abs_path)
            music_playing = abs_path
        else:
            try:
                current_index = song_list.index(music_playing)
            except ValueError:
                current_index = 0
                song_list.insert(0, music_playing)
            abs_path = song_list[current_index + 1]
            music_file_without_endswith = abs_path.split("/")[-1].rsplit(".", 1)[0]
            music_playing = abs_path
        try:
            lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
        except:
            lyric = {}
        music_player.set_format_of_time(
            lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
        playmusic(abs_path)
    if playingmode in [0, 2]:
        refresh()
        music_dir = [file for file in os.listdir(path) if
                     file.endswith(('.mp3', '.flac', '.ogg', '.m4a'))]
        try:
            music_file_name = music_dir[music_dir.index(music_playing.split("/")[-1]) + 1]
            music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
            abs_path = path + "/" + music_file_name
            music_playing = abs_path
            try:
                lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
            except:
                lyric = {}
        except IndexError:
            music_file_name = music_dir[0]
            music_file_without_endswith = music_file_name.split("/")[-1].rsplit(".", 1)[0]
            music_playing = path + "/" + music_file_name
            try:
                lyric = lyrics.load_lyrics(f"{path}/{music_file_without_endswith}.lrc")
            except:
                lyric = {}
        music_player.set_format_of_time(
            lang.get(la, "ui.playing.text.time_format", {"_music_": music_file_without_endswith}))
        playmusic(music_playing)


def entry_focus(boolean):
    global last_search_target
    if boolean:
        if entry.get() == lang.get(la, "ui.download.entry.song_name"):
            var0.set("")
    else:
        if entry.get() == "":
            var0.set(lang.get(la, "ui.download.entry.song_name"))


def entry1_focus(boolean):
    global last_search_target1, focused
    if boolean:
        focused = True
        if entry1.get() == lang.get(la, "ui.download.entry.song_name"):
            var7.set("")
    else:
        focused = False
        if entry1.get() == "":
            var7.set(lang.get(la, "ui.download.entry.song_name"))


def change_playing_mode():
    global playingmode
    if playingmode == 0:
        playingmodeButton["image"] = imagetk7["rand"]
        playingmode += 1
    elif playingmode == 1:
        playingmodeButton["image"] = imagetk7["sequ"]
        playingmode += 1
    else:
        playingmodeButton["image"] = imagetk7["loop"]
        playingmode = 0


def load_versions():
    global version_json
    time.sleep(0.5)
    try:
        resp = requests.get("http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/version_list.json")
        version_json = resp.json()
        resp.close()
        for version_item in version_json:
            list_version = version_item["version"]
            list_upload_time = version_item["upload_time"]
            list_brief = version_item["brief"]
            version_list.insert("", "end", values=(list_version, list_upload_time, list_brief))
    except:
        labelframe_update_log["text"] = lang.get(la, "frame.update_log", {"_version_": "NFLmusic"})


def version_choice(*event):
    global version_download_choice
    try:
        version_download_choice = version_list.selection()[0]
        choice_index = get_treeview_index(version_list, version_download_choice)
        labelframe_update_log["text"] = lang.get(la, "frame.update_log",
                                                 {"_version_": version_json[choice_index]["version"]})
        data["state"] = "normal"
        data.delete(1.0, END)
        data.insert("end", version_json[choice_index]["log"])
        data["state"] = "disabled"
        download_button.place(relx=0.5, rely=0.9, anchor="center")
    except:
        pass


def return_all_log(*event):
    data["state"] = "normal"
    text = logs.get(la)
    data.delete("1.0", END)
    data.insert('end', text)
    data["state"] = "disabled"
    download_button.place_forget()
    labelframe_update_log["text"] = lang.get(la, "frame.update_log", {"_version_": "NFLmusic"})


def download_version():
    version_web = version_json[get_treeview_index(version_list, version_download_choice)]["url"]
    if tkinter.messagebox.askyesno(lang.get(la, "mbox.title.download_web"),
                                   lang.get(la, "mbox.text.download_web", {"_url_": version_web})):
        tkinter.messagebox.showinfo(lang.get(la, "mbox.title.copy_pwd"),
                                    lang.get(la, "mbox.text.copy_pwd",
                                             {"_pwd_": version_json[
                                                 get_treeview_index(version_list, version_download_choice)][
                                                 "password"]}))
        webbrowser.open(version_web)
        copy(version_json[get_treeview_index(version_list, version_download_choice)]["password"])


def search_local_song():
    global search_words, filtered_list, music_dir_without_endswith
    while True:
        if focused:
            former_words = var7.get()
            time.sleep(1)
            current_words = var7.get()
            if former_words != current_words and entry1.get() != lang.get(la, "ui.download.entry.song_name"):
                search_words = current_words
                filtered_list = [song for song in music_dir_without_endswith if search_words in song]
                if not filtered_list:
                    listbox1.unbind("<Double-1>")
                else:
                    listbox1.bind("<Double-1>", playsound)
                print(music_dir_without_endswith)
                listbox1.delete(0, END)
                for song in filtered_list:
                    listbox1.insert(END, song)
        else:
            time.sleep(1)


version = "4.3.4"
poem = ""
appdata = os.getenv("APPDATA")
make_resource()
make_lang_json()
if not os.path.exists(appdata + "/.NFLmusic/NFLmusic.json"):
    make_jsondata()

try:
    with open(appdata + '/.NFLmusic/NFLmusic.json', 'r') as file:
        jsondata = json.loads(file.read())
        la = jsondata["language"]
        theme = tmla.catch(la, jsondata["theme"])
        choice = jsondata["choice"]
        url = ij.api_data[choice][0]
        br_dict = ij.api_data[choice][1]
        br_list = [br for br in br_dict]
        path = jsondata["path"]
        br = jsondata["br"][choice]
        if br not in br_list:
            br = ij.usercache["br"][choice]
        auto_update = jsondata["auto_update"]
        playingmode = jsondata["playing_mode"]
        auto_play = jsondata["auto_play"]
except:
    make_jsondata()
    with open(appdata + '/.NFLmusic/NFLmusic.json', 'r') as file:
        jsondata = json.loads(file.read())
        la = jsondata["language"]
        theme = tmla.catch(la, jsondata["theme"])
        choice = jsondata["choice"]
        url = ij.api_data[choice][0]
        br_dict = ij.api_data[choice][1]
        br_list = [br for br in br_dict]
        path = jsondata["path"]
        br = jsondata["br"][choice]
        if br not in br_list:
            br = ij.usercache["br"][choice]
        auto_update = jsondata["auto_update"]
        playingmode = jsondata["playing_mode"]
        auto_play = jsondata["auto_play"]

theme0 = tmla.get(la)[theme]
style = Style(theme=theme0)
style.configure("Treeview", rowheight=40)
root = style.master
version_json = {}
version_download_choice = 0
song_list_limit = 20
music_player = MusicPlayer(root)
music_playing = ""
music_file_name = ""
music_dir_without_endswith = []
song_list = []
music_file_without_endswith = ""
lyric = ""
last_search_target = ""
last_search_target1 = ""
root.resizable(0, 0)
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 计算窗口左上角的位置使窗口居中
x = (screen_width - 810) // 2
y = (screen_height - 530) // 2
root.geometry(f'810x530+{x}+{y}')
root.title(f"NFLmusic v{version}")
root.protocol('WM_DELETE_WINDOW', save_sth)
downloading = False
var = StringVar()
var0 = StringVar()
var0.set(lang.get(la, "ui.download.entry.song_name"))
var1 = StringVar()
var2 = StringVar()
var3 = BooleanVar()
var3.set(auto_update)
var4 = StringVar()
var5 = StringVar()
var5.set(la)
var6 = BooleanVar()
var6.set(auto_play)
var7 = StringVar()
var7.set(lang.get(la, "ui.download.entry.song_name"))
isJoking = False
changed = False
focused = False
player = None
OptionMenu = ttk.OptionMenu
Button = ttk.Button
Scrollbar = ttk.Scrollbar
Progressbar = ttk.Progressbar
Checkbutton = ttk.Checkbutton
Entry = ttk.Entry
showed = False
page = "homepage"
will_page = "homepage"
former_page = "homepage"
search_words = lang.get(la, "ui.download.entry.song_name")
next_showed = False
loaded = False
have_checked = False
playingmode_dict = {
    0: "loop",
    1: "rand",
    2: "sequ"
}

if path == "./music":
    if os.path.exists("./music"):
        pass
    else:
        os.makedirs("./music")

image1 = Image.open(resource_path + "/.NFLmusic/resource/buttons/playsound.png")
imagetk1 = ImageTk.PhotoImage(image1.resize((20, 20)))
image2 = Image.open(resource_path + "/.NFLmusic/resource/buttons/download.png")
imagetk2 = ImageTk.PhotoImage(image2.resize((16, 16)))
image3 = Image.open(resource_path + "/.NFLmusic/resource/buttons/refresh.png")
imagetk3 = ImageTk.PhotoImage(image3.resize((16, 16)))
image4 = Image.open(resource_path + "/.NFLmusic/resource/buttons/delete.png")
imagetk4 = ImageTk.PhotoImage(image4.resize((16, 16)))
image5 = Image.open(resource_path + "/.NFLmusic/resource/buttons/browse.png")
imagetk5 = ImageTk.PhotoImage(image5.resize((16, 16)))
image6 = Image.open(resource_path + "/.NFLmusic/resource/buttons/pausesound.png")
imagetk6 = ImageTk.PhotoImage(image6.resize((20, 20)))
image7 = {"sequ": Image.open(resource_path + "/.NFLmusic/resource/buttons/playingmode_sequential.png"),
          "rand": Image.open(resource_path + "/.NFLmusic/resource/buttons/playingmode_random.png"),
          "loop": Image.open(resource_path + "/.NFLmusic/resource/buttons/playingmode_loop.png")}
imagetk7 = {"sequ": ImageTk.PhotoImage(image7["sequ"].resize((16, 16))),
            "rand": ImageTk.PhotoImage(image7["rand"].resize((16, 16))),
            "loop": ImageTk.PhotoImage(image7["loop"].resize((16, 16)))}
image8 = Image.open(resource_path + "/.NFLmusic/resource/images/logo.png")
imagetk8 = ImageTk.PhotoImage(image8.resize((256, 256)))
image9 = Image.open(resource_path + "/.NFLmusic/resource/buttons/former.png")
imagetk9 = ImageTk.PhotoImage(image9.resize((20, 20)))
image0 = Image.open(resource_path + "/.NFLmusic/resource/buttons/latter.png")
imagetk0 = ImageTk.PhotoImage(image0.resize((20, 20)))

run(opening_animation)

label_image = Label(root, image=imagetk8)
label_image.place(relx=0.5, rely=0.5, anchor="center")

# 主页
homepage_frame = ttk.Frame(root, width=1000, height=1000)

labelframe_playing_settings = ttk.Labelframe(homepage_frame, text=lang.get(la, "frame.playing_settings"), width=770,
                                             height=120)
labelframe_playing_settings.place(x=20, y=380)

# 操控按钮
button_x = 15
button_y = 9
play_button_y = 7
formerButton = Button(labelframe_playing_settings, image=imagetk9, style="Link.TButton", command=former_song)
formerButton.place(x=button_x + 45, y=play_button_y)
latterButton = Button(labelframe_playing_settings, image=imagetk0, style="Link.TButton", command=latter_song)
latterButton.place(x=button_x + 135, y=play_button_y)
playsoundButton = Button(labelframe_playing_settings, command=pausesound, image=imagetk1, style="Link.TButton")
playsoundButton.place(x=button_x + 90, y=play_button_y)
playingmodeButton = Button(labelframe_playing_settings, command=change_playing_mode,
                           image=imagetk7[playingmode_dict[playingmode]], style="Link.TButton")
playingmodeButton.place(x=button_x + 180, y=button_y)
refreshButton = Button(labelframe_playing_settings, command=refresh, style="Link.TButton", image=imagetk3)
refreshButton.place(x=button_x, y=button_y)
deleteButton = Button(labelframe_playing_settings, command=delete, style="Link.TButton", image=imagetk4)
deleteButton.place(x=button_x + 225, y=button_y)

playing_time = ttk.Label(labelframe_playing_settings, text="")
playing_time.place(relx=0.03, rely=0.5)

music_lrc = ttk.Label(labelframe_playing_settings, text=lyric, style="Link.TLabel", font=("黑体", 15),
                      foreground="orange")
music_lrc.place(relx=0.65, rely=0.3, anchor="center")

playing_progress = ttk.Scale(labelframe_playing_settings, length=730, from_=0, to=1)
playing_progress.place(x=20, y=70)

labelframe_song_list = ttk.Labelframe(homepage_frame, text=lang.get(la, "frame.song_list"), width=250,
                                      height=354)
labelframe_song_list.place(x=20, y=20)

scrollbar1 = Scrollbar(labelframe_song_list, orient=VERTICAL)

listbox1 = Listbox(labelframe_song_list, width=30, height=16, yscrollcommand=scrollbar1.set)
listbox1.place(x=10, y=0)
listbox1.bind("<Double-1>", playsound)

entry1 = Entry(labelframe_song_list, width=31, textvariable=var7)
entry1.bind("<FocusIn>", lambda event: entry1_focus(True))
entry1.bind("<FocusOut>", lambda event: entry1_focus(False))
entry1.place(x=10, y=295)

scrollbar1.config(command=listbox1.yview)
scrollbar1.place(x=227, y=0, height=292)

refresh()
filtered_list = music_dir_without_endswith

labelframe_download = ttk.Labelframe(homepage_frame, text=lang.get(la, "frame.download"), height=354, width=510)
labelframe_download.place(x=280, y=20)

scrollbar2 = Scrollbar(labelframe_download, orient=VERTICAL)

songlist = ttk.Treeview(labelframe_download, columns=("Song", "Artist", "Album"), height=5, show="headings",
                        yscrollcommand=scrollbar2.set)
songlist.heading("Song", text=lang.get(la, "ui.download.treeview.song"))
songlist.heading("Artist", text=lang.get(la, "ui.download.treeview.artist"))
songlist.heading("Album", text=lang.get(la, "ui.download.treeview.album"))
songlist.column("Song", width=160, minwidth=160)
songlist.column("Artist", width=160, minwidth=160)
songlist.column("Album", width=160, minwidth=160)
songlist.place(x=5, y=50)
songlist.bind("<Double-1>", download_check)

scrollbar2.config(command=songlist.yview)
scrollbar2.place(x=490, y=50, height=235)

button0 = Button(labelframe_download, text=lang.get(la, "ui.download.button.search"),
                 command=lambda: get_data_without_blocking(var0.get()), style="Outline.TButton")
button0.place(x=230, y=10)

Label(labelframe_download, text=lang.get(la, "ui.download.text.song_name")).place(x=10, y=14)
Label(labelframe_download, text=lang.get(la, "ui.download.text.sound_quality")).place(x=310, y=14)
entry = Entry(labelframe_download, textvariable=var0)
entry.place(x=70, y=10)
entry.bind("<Return>", lambda event: get_data_without_blocking(var0.get()))
entry.bind("<FocusIn>", lambda event: entry_focus(True))
entry.bind("<FocusOut>", lambda event: entry_focus(False))

menu0 = OptionMenu(labelframe_download, var, br, *br_list)
menu0.place(x=370, y=10)

# 设置页面
setting_frame = Frame(root, width=1000, height=1000)
labelframe_settings = ttk.Labelframe(setting_frame, text=lang.get(la, "frame.base_settings"),
                                     height=480, width=500)
labelframe_settings.place(x=20, y=20)

# 关于页面
about_frame = Frame(root, width=1000, height=1000)

labelframe_treasure_chest = ttk.LabelFrame(about_frame, text=lang.get(la, "frame.treasure_chest"),
                                           height=210, width=500)
labelframe_treasure_chest.place(x=20, y=20)

random_quote = Label(labelframe_treasure_chest, text="", font=("楷体", 18))
random_quote.place(relx=0.5, rely=0.2, anchor="center")

do_not_click_button = Button(labelframe_treasure_chest, text=lang.get(la, "ui.about.button.do_not_click"),
                             style="danger.Outline.TButton", width=30, command=do_not_click)
do_not_click_button.place(relx=0.5, rely=0.7, anchor="center")

labelframe_about = ttk.LabelFrame(about_frame, text=lang.get(la, "frame.about"),
                                  height=261, width=500)
labelframe_about.place(x=20, y=240)

label0 = Label(labelframe_about, text="")
label0.place(x=30, y=10)

announcement = Label(labelframe_about, text="")
announcement.place(x=300, y=10)

run(display_sentences)

labelframe_thanks = LabelFrame(about_frame, text=lang.get(la, "frame.thanks"), height=480, width=250, )
labelframe_thanks.place(x=540, y=20)

# 鸣谢
oiapi = "https://oiapi.net/"
githook = "http://git.nanfengling.cn/"
nanfect = "http://pan.nanfengling.cn/"
skylark = "https://space.bilibili.com/1868716664"
sponsorship = "https://afdian.com/a/NFLstudio"

lb0 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.music_url'),
         button=lang.get(la, 'ui.thanks.button.music_url'), command=lambda: webbrowser.open(oiapi))
lb0.place(button=(80, 15), label=(10, 20))
lb1 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.random_poem'),
         button=lang.get(la, 'ui.thanks.button.random_poem'), command=lambda: webbrowser.open(githook))
lb1.place(button=(80, 55), label=(10, 60))
lb2 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.file_store'),
         button=lang.get(la, 'ui.thanks.button.file_store'), command=lambda: webbrowser.open(nanfect))
lb2.place(button=(80, 95), label=(10, 100))
lb3 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.bug_fix'),
         button=lang.get(la, 'ui.thanks.button.bug_fix'), command=lambda: webbrowser.open(skylark))
lb3.place(button=(80, 135), label=(10, 140))
lb4 = lb(pack_box=labelframe_thanks, label=lang.get(la, 'ui.thanks.text.sponsorship'),
         button=lang.get(la, 'ui.thanks.button.sponsorship'), command=lambda: webbrowser.open(sponsorship))
lb4.place(button=(80, 175), label=(10, 180))

scrollbar3 = Scrollbar(labelframe_thanks, orient=VERTICAL)
sponsors_list = Listbox(labelframe_thanks, height=13, width=30, yscrollcommand=scrollbar3.set)
sponsors_list.place(x=10, y=210)
scrollbar3.config(command=sponsors_list.yview)
scrollbar3.place(x=227, y=210, height=240)
try:
    data_url = "http://git.nanfengling.cn/NFL_jiancx/NFLmusic/raw/branch/master/version_info/sponsors"
    data_resp = requests.get(data_url)
    data_list = data_resp.text.replace("\r", "").split("\n")
    for sponsor in data_list:
        sponsors_list.insert("end", sponsor)
    data_resp.close()
except:
    pass

# 开发版本页面
version_frame = Frame(root, width=1000, height=1000)
current_version = Label(version_frame, font=("微软雅黑", 10),
                        text=lang.get(la, "ui.versions.text.current_version", {"_version_": version}))
current_version.place(relx=0.4, rely=0.08, anchor="center")

labelframe_version_list = LabelFrame(version_frame, text=lang.get(la, "frame.version_list"),
                                     height=350, width=500)
labelframe_version_list.place(x=20, y=140)

scrollbar4 = Scrollbar(labelframe_version_list, orient=VERTICAL)

version_list = ttk.Treeview(labelframe_version_list, style="success.Treeview",
                            columns=("Version", "UploadTime", "UpdateBrief"), height=6,
                            show="headings", yscrollcommand=scrollbar4.set)
version_list.heading("Version", text=lang.get(la, "ui.versions.treeview.version"))
version_list.heading("UploadTime", text=lang.get(la, "ui.versions.treeview.upload_time"))
version_list.heading("UpdateBrief", text=lang.get(la, "ui.versions.treeview.update_brief"))
version_list.column("Version", width=100, minwidth=100)
version_list.column("UploadTime", width=100, minwidth=100)
version_list.column("UpdateBrief", width=250, minwidth=250)
version_list.place(x=20, y=20)
version_list.bind("<Double-1>", version_choice)
version_list.bind("<Button-3>", return_all_log)
scrollbar4.config(command=version_list.yview)
scrollbar4.place(x=475, y=40, height=255)

labelframe_update_log = ttk.LabelFrame(version_frame, text=lang.get(la, "frame.update_log", {"_version_": "NFLmusic"}),
                                       height=350,
                                       width=250)
labelframe_update_log.place(x=540, y=140)

# 更新日志
scrollbar = Scrollbar(labelframe_update_log, orient=VERTICAL)
data = Text(labelframe_update_log, width=29, height=14, yscrollcommand=scrollbar.set)
data.place(x=10, y=16)
scrollbar.config(command=data.yview)
scrollbar.place(x=230, y=10, height=265)
download_button = Button(labelframe_update_log, image=imagetk2, style="warning.TButton",
                         command=lambda: download_version())
return_all_log()

run(load_versions)

# 菜单栏
menubar = Menu(root)
menubar.add_command(label=lang.get(la, "menu.homepage"), command=ExchangeGUI.home_page)
menubar.add_command(label=lang.get(la, "menu.settings"), command=ExchangeGUI.window_settings)
menubar.add_command(label=lang.get(la, "menu.about"), command=ExchangeGUI.about)
menubar.add_command(label=lang.get(la, "menu.versions"), command=ExchangeGUI.versions)

themeLabel = Label(labelframe_settings, text=lang.get(la, "ui.settings.text.theme", ))
themeLabel.place(x=10, y=25)

# 基本设置
repo_dict = {
    "酷我音乐": "KUWO",
    "QQ音乐": "QQ",
    "网易云音乐": "WANGYIYUN",
    "酷狗音乐": "KUGOU",
    "聚合搜索": "JUHE"
}
repo_dict_reverse = {}
for repo in repo_dict:
    repo_dict_reverse[repo_dict[repo]] = repo
repo_list = [repo for repo in repo_dict]

language_list = lang.list_languages()

label3 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.download_source', ))
label3.place(x=10, y=65)

if repo_dict_reverse.get(jsondata["choice"]) is None:
    jsondata["choice"] = "KUWO"

menu0 = OptionMenu(labelframe_settings, var4, repo_dict_reverse[jsondata["choice"]],
                   *repo_list)
menu0.place(x=80, y=60)

label1 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.download_position', ))
label1.place(x=10, y=105)
entry0 = Entry(labelframe_settings, textvariable=var2, width=20)
entry0.place(x=80, y=100)
button1 = Button(labelframe_settings, image=imagetk5, command=open_file_dialog)
button1.place(x=240, y=100)

label2 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.auto_update', ))
label2.place(x=10, y=142)
check_button1 = Checkbutton(labelframe_settings, variable=var3, style="Squaretoggle.Toolbutton",
                            text=lang.get(la, "ui.settings.check_button.auto_update", ))
check_button1.place(x=80, y=140)

label3 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.text.language', ))
label3.place(x=10, y=175)

lang_optionmenu = OptionMenu(labelframe_settings, var5, jsondata["language"], *language_list)
lang_optionmenu.place(x=50, y=170)

label4 = Label(labelframe_settings, text=lang.get(la, 'ui.settings.button.auto_play', ))
label4.place(x=10, y=212)
check_button2 = Checkbutton(labelframe_settings, variable=var6, style="Squaretoggle.Toolbutton",
                            text=lang.get(la, "ui.settings.check_button.auto_play", ))
check_button2.place(x=80, y=210)

check_update_button = Button(labelframe_settings, text=lang.get(la, 'ui.settings.button.check_update', ),
                             command=check_update, style="info.Outline.TButton")
check_update_button.place(x=10, y=240)

menu1 = OptionMenu(labelframe_settings, var1, theme, *list(tmla.get(la).keys()))
menu1.place(x=50, y=20)

root.iconbitmap(resource_path + "/.NFLmusic/resource/icon.ico")

run(search_local_song)
run(tick)
music_player.bind(cls_time=playing_time, cls_progress_bar=playing_progress)
playing_progress["command"] = lambda event: music_player.set_progress(playing_progress.get())
music_player.set_format_of_time(lang.get(la, "ui.playing.text.time_format", {"_music_": ""}))

root.mainloop()
