import os
import random
import tkinter as tk
from tkinter import ttk
import pygame
import subprocess

# =============================
# CONFIG
# =============================
PLAYLISTS_DIR = "playlists"  # Folder that contains subfolders
PULSE_SPEED = 40  # ms speed of background color pulse
bluetooth_mode = False

# =============================
# AUDIO SETUP
# =============================
pygame.mixer.pre_init(
    frequency=44100,
    size=-16,
    channels=2,
    buffer=4096
)
pygame.mixer.init()

current_playlist = None
current_playlist_songs = []
playing = False
paused = False
playlist_songs = []
pulse_phase = 40

# =============================
# MAIN WINDOW
# =============================
root = tk.Tk()
root.title("Raspberry Pi Jukebox")
root.geometry("800x480")
root.attributes("-fullscreen", False)

# Changing Menus
def clear_screen():
    for widget in root.winfo_children():
        widget.destroy()

# Background pulse

#def pulse_background():
    #global pulse_phase

    # Only animate if music is playing
    #if playing and not paused:
        #pulse_phase += 0.01

    # Smooth blue <-> purple pulse
    #import math

    #blue_amount = int(180 + 75 * math.sin(pulse_phase))
    #red_amount = int(80 + 60 * math.sin(pulse_phase))

    #color = f"#{red_amount:02x}00{blue_amount:02x}"

    # MAIN WINDOW
    #root.configure(bg=color)

    # SCROLLABLE PLAYLIST AREA
    #playlist_frame_canvas.configure(bg=color)
    #playlists_inner_frame.configure(bg=color)

    # IMPORTANT:
    # This removes ugly gray boxes
    #controls_frame.configure(bg=color)
    #status_label.configure(bg=color)

    # If you have another frame around playlists,
    # add it here too:
    # playlist_container.configure(bg=color)

    # Loop forever
    #root.after(PULSE_SPEED, pulse_background)

# =============================
# PLAYLIST SYSTEM
# =============================

def load_playlists():
    playlists = [d for d in os.listdir(PLAYLISTS_DIR) if os.path.isdir(os.path.join(PLAYLISTS_DIR, d))]
    return playlists

# =============================
# MUSIC PLAYER
# =============================

def play_random_song():
    global playing, paused
    if not playlist_songs:
        status_var.set("No songs in playlist.")
        return
    song = random.choice(playlist_songs)
    pygame.mixer.music.load(song)
    pygame.mixer.music.play()
    playing = True
    paused = False
    status_var.set(f"Playing: {os.path.basename(song)}")
    #pulse_background()


def toggle_play_pause():
    global paused, playing
    if bluetooth_mode:
        return
    if not playing:
        play_random_song()
        play_button.config(text="Pause")
        return
    if paused:
        pygame.mixer.music.unpause()
        paused = False
        play_button.config(text="Pause")
        #pulse_background()
    else:
        pygame.mixer.music.pause()
        paused = True
        play_button.config(text="Play")

def check_song_end():
    global playing
    
    if playing and not paused and not pygame.mixer.music.get_busy():
        next_song()
    
    root.after(1000, check_song_end)

def next_song():
    play_random_song()


def select_playlist(name):
    global current_playlist, playlist_songs
    current_playlist = name
    folder = os.path.join(PLAYLISTS_DIR, name)
    playlist_songs = [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith('.mp3')]
    status_var.set(f"Selected playlist: {name}")
    highlight_selected(name)
    
def highlight_selected(name):
    for widget in playlists_inner_frame.winfo_children():
        if isinstance(widget, tk.Button):
            if widget.cget("text") == name:
                widget.config(bg="#00aa00", fg="black")
            else:
                widget.config(bg="#222", fg="white")

def play_selected_song(song_name):
    global playing
    global paused
    
    folder = os.path.join(PLAYLISTS_DIR, current_playlist)
    
    song_path = os.path.join(folder, song_name)
    
    pygame.mixer.music.load(song_path)
    pygame.mixer.music.play()
    
    playing = True
    paused = False
    
    status_var.set(f"Playing: {song_name}")

def get_device_name():
    try:
        result = subprocess.check_output(
            ["bluetoothctl", "show"],
            text=True
        )
        
        for line in result.splitlines():
            if "Name:" in line:
                return line.split("Name:")[1].strip()
    
    except:
        return "Unknown"
    
    return "Unknown Device"
                
def exit_bluetooth_mode():
    global bluetooth_mode
    bluetooth_mode = False
    show_main_menu()
    

# =============================
# main menu
# =============================

def show_main_menu():
    clear_screen()
    
    global playlist_frame_canvas
    playlist_frame_canvas = tk.Canvas(root, highlightthickness=0)
    playlist_scrollbar = tk.Scrollbar(root, orient="vertical", command=playlist_frame_canvas.yview)
    playlist_scrollbar.pack(side="right", fill="y")
    playlist_frame_canvas.pack(side="top", fill="both", expand=True)
    playlist_frame_canvas.configure(yscrollcommand=playlist_scrollbar.set)
    
    global playlists_inner_frame
    playlists_inner_frame = tk.Frame(playlist_frame_canvas)
    playlist_frame_canvas.create_window((0, 0), window=playlists_inner_frame, anchor="nw")
    
    
    def populate_playlist_buttons():
        playlists = load_playlists()
        for widget in playlists_inner_frame.winfo_children():
            widget.destroy()

        row = 0
        col = 0
        for name in playlists:
            b = tk.Button(playlists_inner_frame, text=name, width=18, height=8,
                        command=lambda n=name: select_playlist(n),
                        bg="#222", fg="white",
                        font=("Arial", 30, "bold"),
                        activebackground="#55aa55")
            b.grid(row=row, column=col, padx=10, pady=10)
            b.bind(
                "<Double-Button-1>",
                lambda event, n=name: show_song_select_menu(n)
            )
            
            col += 1
            if col >= 3:
                col = 0
                row += 1
    
        playlists_inner_frame.update_idletasks()
        playlist_frame_canvas.configure(scrollregion=playlist_frame_canvas.bbox("all"))
    
    
    # CONTROLS
    
    global status_var
    status_var = tk.StringVar(value="Select yo playlist.")
    status_label = tk.Label(root, textvariable=status_var, font=("Arial", 30, "bold"))
    status_label.pack(pady=10)
    
    controls_frame = tk.Frame(root)
    controls_frame.pack(pady=5)
    
    global play_button
    play_button = tk.Button(controls_frame, text="Play", width=14, height=3, font=("Arial", 20, "bold"), command=toggle_play_pause)
    next_button = tk.Button(controls_frame, text="Next", width=14, height=3, font=("Arial", 20, "bold"), command=next_song)
    refresh_button = tk.Button(root, text="Refresh Playlists", command=populate_playlist_buttons)
    
    play_button.grid(row=0, column=0, padx=35, pady=15)
    next_button.grid(row=0, column=1, padx=35, pady=15)
    refresh_button.pack(side="bottom", pady=10)
    
    bluetooth_button = tk.Button(root, text="Bluetooth Speaker Mode", font=("Arial", 18, "bold"), width=24, height=3, command=show_bluetooth_menu)
    bluetooth_button.pack(pady=20)
    
    populate_playlist_buttons()

# =============================
# main menu
# =============================

def show_song_select_menu(current_playlist):
    global current_playlist_songs

    clear_screen()

    title = tk.Label(
        root,
        text=current_playlist,
        font=("Arial", 28, "bold")
    )
    
    song_frame = tk.Frame(root)
    song_frame.pack(fill="both", expand=True)
    
    song_canvas = tk.Canvas(song_frame)
    scrollbar=tk.Scrollbar(song_frame, orient="vertical", command=song_canvas.yview)
    
    scrollable_songs = tk.Frame(song_canvas)
    
    scrollable_songs.bind(
        "<Configure>",
        lambda e: song_canvas.configure(
            scrollregion=song_canvas.bbox("all")
        )
    )
    
    song_canvas.create_window((0, 0), window=scrollable_songs, anchor="nw")
    
    song_canvas.configure(yscrollcommand=scrollbar.set)
    
    song_canvas.pack(side="left", fill="both", expand=True)
    scrollbar.pack(side="right", fill="y")
    
    folder = os.path.join(PLAYLISTS_DIR, current_playlist)
    
    current_playlist_songs = [
        f for f in os.listdir(folder)
        if f.endswith(".mp3")
    ]
    
    for song in current_playlist_songs:
        btn = tk.Button(
            scrollable_songs,
            text=song.replace(".mp3", ""),
            font=("Arial", 18),
            width=140,
            height=2,
            command=lambda s=song: play_selected_song(s)
        )
        
        btn.pack(fill="x", padx=25, pady=5)
    
    back_button = tk.Button(
        root,
        text="Return by Jukebox",
        font=("Arial", 20, "bold"),
        width=20,
        height=2,
        command=show_main_menu
    )
    
    back_button.pack(pady=20)

# =============================
# bluetooth menu
# =============================

def show_bluetooth_menu():
    global bluetooth_mode, playing, paused
    
    bluetooth_mode = True
    device_name = get_device_name()
    
    clear_screen()
    
    #stop th music
    pygame.mixer.music.stop()
    playing = False
    paused = False
    
    title = tk.Label(
        root,
        text="Bluetooth Speaker Mode",
        font=("Arial", 30, "bold")
    )
    title.pack(pady=40)
    
    info = tk.Label(
        root, text="Connect yo phone gng so you can listen to sum music",
        font=("Arial", 18)
    )
    info.pack(pady=20)
    
    status = tk.Label(
        root,
        text="Online Omega Matrix Initialized. Accessing the mainframe. Further Nerd Jargon.",
        font=("Arial", 7)
    )
    status.pack(pady=10)
    
    name_label = tk.Label(
        root,
        text=f"Running on: {device_name}",
        font=("Arial", 20)
    )
    name_label.pack(pady=15)
    
    back_button = tk.Button(
        root,
        text="Return by Jukebox",
        font=("Arial", 20, "bold"),
        width=18,
        height=3,
        command=exit_bluetooth_mode
    )
    back_button.pack(pady=40)


# =============================
# INITIALIZE
# =============================

import math
show_main_menu()

check_song_end()

root.mainloop()
