import json
import requests
from acrcloud.recognizer import ACRCloudRecognizer
from musixmatch_api import Musixmatch, CaptchaError, UserTokenError
from mutagen.mp3 import MP3
from mutagen.id3 import ID3, APIC, error

# ACRCloud API credentials
ACR_HOST = ""
ACR_ACCESS_KEY = ""
ACR_ACCESS_SECRET = ""

# ACR Cloud configuration (update with your credentials)
config = {
    'host': ACR_HOST,
    'access_key': ACR_ACCESS_KEY,
    'access_secret': ACR_ACCESS_SECRET,
    'timeout': 10  # seconds
}

recognizer = ACRCloudRecognizer(config)

# Initialize Musixmatch API (exception handling to be added as per your implementation)
musixmatch = Musixmatch(Exception)

# Function to recognize a song using ACRCloud
def recognize_song(audio_file_path):
    buffer = open(audio_file_path, 'rb').read()
    result = recognizer.recognize_by_filebuffer(buffer, 0)
    try:
        result_dict = json.loads(result)
        return result_dict['metadata']['music'][0]
    except (KeyError, IndexError, json.JSONDecodeError) as e:
        print(f"Error while parsing result: {e}")
        return None

def format_time(ts):
    '''Converts time in seconds to the format [mm:ss.xx]'''
    minutes = int(ts // 60)
    seconds = int(ts % 60)
    hundredths = int((ts - int(ts)) * 100)
    return f'[{minutes:02d}:{seconds:02d}.{hundredths:02d}]'

def process_rich_sync_lyrics(rich_sync_lyrics_json):
    '''Converts Musixmatch rich sync data to LRC format'''
    lrc_lines = []
    try:
        # Load the JSON string into a Python object
        rich_sync_data = json.loads(rich_sync_lyrics_json)
    except json.JSONDecodeError as e:
        print(f"Error decoding JSON: {e}")
        return None

    # Iterate through each line and create formatted LRC lines
    for line in rich_sync_data:
        ts = format_time(line['ts'])  # Start time of the line
        lrc_line = f'{ts}{line["x"]}'  # Use "x" for the entire line of lyrics
        lrc_lines.append(lrc_line)

    # Join the formatted lines with line breaks
    return '\n'.join(lrc_lines)


# Function to get lyrics from Musixmatch given artist name and song title
def get_lyrics_from_musicxmatch(artist_name, song_title):
    try:
        user_token = musixmatch.get_user_token()
        
        track_data = musixmatch.get_search_by_track(song_title, artist_name, "")
        if track_data:
            track_id = track_data['track_id']
            rich_sync_data = musixmatch.get_rich_sync_by_id(track_id)
            
            # Print the JSON response for debugging
            print(json.dumps(track_data, indent=2))
            print(json.dumps(rich_sync_data, indent=2))

            if rich_sync_data and 'richsync_body' in rich_sync_data:
                rich_sync_lyrics_json = rich_sync_data['richsync_body']
                lrc_lyrics = process_rich_sync_lyrics(rich_sync_lyrics_json)
                return lrc_lyrics
            else:
                print("No synced lyrics found.")
                return None
        else:
            print("Track not found in Musixmatch.")
            return None
    except (CaptchaError, UserTokenError) as e:
        print(f"Error while working with Musixmatch: {e}")
        return None

if __name__ == "__main__":
    audio_file_path = 'C:/Users/ILEG-i5-11/Downloads/Music/Unknown_file.mp3'  # Replace this path
    lrc_file_path = 'C:/Users/ILEG-i5-11/Downloads/Music/Unknown_file.lrc'  # Output LRC file path

    # Recognize the song using ACRCloud
    song_tags = recognize_song(audio_file_path)
    if song_tags:
        artist_name = song_tags['artists'][0]['name']
        song_title = song_tags['title']
        print(f"Identified Song: {artist_name} - {song_title}")
        track_data = musixmatch.get_search_by_track(song_title, artist_name, "")
        if track_data:
            album_id = track_data.get('album_id')
            if album_id:
                album_cover_url = musixmatch.get_album_cover_url(album_id)
                album_cover_save_path = 'C:/Users/ILEG-i5-11/Downloads/Music/Album_Cover.jpg'
                download_album_cover(album_cover_url, album_cover_save_path)
                print(f"Album cover saved to: {album_cover_save_path}")
                # Embed 350x350 album art into the mp3 file
                embed_album_art(audio_file_path, album_cover_save_path)
                print("Album art embedded into the MP3 file.")
        # Fetch the synced lyrics (rich sync) using the recognized song information
        lrc_lyrics = get_lyrics_from_musicxmatch(artist_name, song_title)
        if lrc_lyrics:
            # Write the LRC lyrics to a file
            with open(lrc_file_path, 'w', encoding='utf-8') as lrc_file:
                lrc_file.write(lrc_lyrics)
            print(f"Saved LRC file to: {lrc_file_path}")
        else:
            print("Could not get the lyrics.")
    else:
        print("Could not identify the song.")


like get album covers for the identified song and embedd the cover to the detected song in 350x350 and save externally in 1400x1400.