# pylint: disable=broad-exception-caught

"""Music recognition using Shazam API."""

import asyncio
import threading
import uuid

import requests
from shazamio_core import Recognizer


URL = (
    "https://amp.shazam.com/discovery/v5/{language}/{endpoint_country}/{device}/-/tag/{uuid_1}/{uuid_2}"
    "?sync=true&webv3=true&sampling=true&connected=&shazamapiversion=v3"
    "&sharehub=true&hubv5minorversion=v5.1&hidelb=true&video=v3"
)

HEADERS = {
    "X-Shazam-Platform": "IPHONE",
    "X-Shazam-AppVersion": "14.1.0",
    "Accept": "*/*",
    "Accept-Language": "en-US",
    "Accept-Encoding": "gzip, deflate",
    "User-Agent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_3 like Mac OS X; en-us) "
    "AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7E18 Safari/528.16",
}


def sync_get_signature(file_path):
    """
    Synchronous wrapper for the async shazam.recognize function that
    works even when called from within another running event loop.
    """
    done_event = threading.Event()
    result_container = []
    error_container = []

    def run_in_new_thread():
        async def recognize_path(file_path):
            core_recognizer = Recognizer(segment_duration_seconds=15)
            return await core_recognizer.recognize_path(file_path)

        try:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            try:
                result = loop.run_until_complete(recognize_path(file_path))
                result_container.append(result)
            finally:
                asyncio.set_event_loop(None)
                loop.close()
        except Exception as e:
            error_container.append(e)
        finally:
            done_event.set()

    thread = threading.Thread(target=run_in_new_thread)
    thread.daemon = True
    thread.start()
    done_event.wait()

    if error_container:
        raise error_container[0]

    return result_container[0] if result_container else None


def audio_recognize(file_path: str) -> str | None:
    """
    Recognize music in an audio file using Shazam.

    Args:
        file_path: Path to audio file (mp3, wav, etc.)

    Returns:
        Track title if music detected, None otherwise
    """
    try:
        signature = sync_get_signature(file_path)
        data = {
            "timezone": "Europe/Moscow",
            "signature": {
                "uri": signature.signature.uri,
                "samplems": signature.signature.samples,
            },
            "timestamp": signature.timestamp,
            "context": {},
            "geolocation": {},
        }
        response = requests.post(
            URL.format(
                language="en-US",
                device="web",
                endpoint_country="GB",
                uuid_1=str(uuid.uuid4()).upper(),
                uuid_2=str(uuid.uuid4()).upper(),
            ),
            headers=HEADERS,
            json=data,
            timeout=10,
        )
        response.raise_for_status()
        matches = response.json()["matches"]
        if len(matches) > 0:
            return response.json()["track"]["title"]
        return None
    except Exception:
        return None
