#sync_spotify
import json
import os
import spotipy
from spotipy.oauth2 import SpotifyOAuth

# 1. Configurações e Variáveis de Ambiente
SPOTIPY_CLIENT_ID = os.environ.get("SPOTIPY_CLIENT_ID")
SPOTIPY_CLIENT_SECRET = os.environ.get("SPOTIPY_CLIENT_SECRET")
SPOTIPY_REDIRECT_URI = os.environ.get("SPOTIPY_REDIRECT_URI")
ARQUIVO_DADOS = os.path.expanduser("~/spotify_biblioteca.json")

# Validação das credenciais no ambiente
if not SPOTIPY_CLIENT_ID or not SPOTIPY_CLIENT_SECRET:
    raise ValueError("Credenciais do Spotify não foram encontradas no ambiente!")

# Instância do Spotipy
sp = spotipy.Spotify(
    auth_manager=SpotifyOAuth(
        client_id=SPOTIPY_CLIENT_ID,
        client_secret=SPOTIPY_CLIENT_SECRET,
        redirect_uri=SPOTIPY_REDIRECT_URI,
        scope="user-library-read playlist-read-private playlist-read-collaborative",
        cache_path=".cache_spotify",
        open_browser=False,
    )
)


def extrair_faixa(item: dict, nova_biblioteca: dict) -> bool:
    """Extrai as informações relevantes da faixa e insere no dicionário."""
    if not item:
        return False

    # Lida com variações de resposta do payload da API
    track = item.get("track") or item.get("item")
    if not track:
        return False

    uri = track.get("uri", "")
    nome = track.get("name", "").strip()

    # Filtra itens locais ou sem URI válida de faixa
    if not uri or "spotify:track:" not in uri or not nome:
        return False

    # Formata lista de artistas
    artistas_lista = track.get("artists", [])
    nomes_artistas = [
        art.get("name", "").strip()
        for art in artistas_lista
        if art and art.get("name")
    ]
    artistas = " ".join(nomes_artistas)

    # Cria chave única baseada no nome e artistas
    chave = f"{nome} {artistas}".strip().lower()
    nova_biblioteca[chave] = uri
    return True


def sincronizar_spotify():
    nova_biblioteca = {}

    try:
        meu_perfil = sp.current_user()
    except Exception as e:
        print(f"[!] Erro ao autenticar ou buscar perfil do usuário: {e}")
        return

    if not meu_perfil:
        print("[!] Não foi possível obter o perfil do usuário.")
        return

    meu_id = meu_perfil.get("id")
    nome_usuario = meu_perfil.get("display_name", meu_id)
    print(f"\nUsuário detectado: {nome_usuario}\n")

    # 1. Sincronizar Músicas Curtidas (Lojas da Biblioteca)
    print("Sincronizando Músicas Curtidas...")
    curtidas_count = 0
    try:
        resultados = sp.current_user_saved_tracks(limit=50)
        while resultados:
            for item in resultados.get("items", []):
                if extrair_faixa(item, nova_biblioteca):
                    curtidas_count += 1
            resultados = (
                sp.next(resultados) if resultados.get("next") else None
            )
        print(f" [+] {curtidas_count} faixas processadas nas curtidas.\n")
    except Exception as e:
        print(f" [!] Erro ao ler faixas curtidas: {e}\n")

    # 2. Sincronizar Playlists Criadas pelo Usuário
    print("Sincronizando Playlists Criadas por Mim...")
    try:
        playlists = sp.current_user_playlists(limit=50)
        while playlists:
            for playlist in playlists.get("items", []):
                if not playlist or not playlist.get("owner"):
                    continue

                # Processa apenas playlists que pertençam ao usuário logado
                if playlist["owner"].get("id") != meu_id:
                    continue

                nome_playlist = playlist.get("name", "Playlist Desconhecida")
                playlist_id = playlist.get("id")
                print(f" -> Lendo: {nome_playlist}")

                try:
                    faixas = sp.playlist_items(playlist_id, limit=50)
                    lidas = 0
                    while faixas:
                        for item in faixas.get("items", []):
                            if extrair_faixa(item, nova_biblioteca):
                                lidas += 1
                        faixas = (
                            sp.next(faixas) if faixas.get("next") else None
                        )
                    print(f"    [+] {lidas} faixas salvas.")
                except Exception as e:
                    print(f"    [!] Erro ao ler faixas da playlist: {e}")

            playlists = sp.next(playlists) if playlists.get("next") else None
    except Exception as e:
        print(f" [!] Erro ao buscar playlists: {e}")

    # 3. Salvar Dicionário Final em Arquivo JSON
    try:
        with open(ARQUIVO_DADOS, "w", encoding="utf-8") as f:
            json.dump(nova_biblioteca, f, ensure_ascii=False, indent=4)
        print(
            f"\nSucesso! {len(nova_biblioteca)} músicas únicas salvas em '{ARQUIVO_DADOS}'."
        )
    except IOError as e:
        print(f"\n[!] Erro ao salvar o arquivo JSON: {e}")


if __name__ == "__main__":
    sincronizar_spotify()