import json
import locale
import re
import time
import unicodedata
from hashlib import sha1
from http.cookies import SimpleCookie

from ytmusicapi.constants import *


def initialize_headers():
    return {
        "user-agent": USER_AGENT,
        "accept": "*/*",
        "accept-encoding": "gzip, deflate",
        "content-type": "application/json",
        "content-encoding": "gzip",
        "origin": YTM_DOMAIN,
    }


def initialize_context():
    return {
        "context": {
            "client": {
                "clientName": "WEB_REMIX",
                "clientVersion": "1." + time.strftime("%Y%m%d", time.gmtime()) + ".01.00",
            },
            "user": {},
        }
    }


def get_visitor_id(request_func):
    response = request_func(YTM_DOMAIN)
    matches = re.findall(r"ytcfg\.set\s*\(\s*({.+?})\s*\)\s*;", response.text)
    visitor_id = ""
    if len(matches) > 0:
        ytcfg = json.loads(matches[0])
        visitor_id = ytcfg.get("VISITOR_DATA")
    return {"X-Goog-Visitor-Id": visitor_id}


def sapisid_from_cookie(raw_cookie):
    cookie = SimpleCookie()
    cookie.load(raw_cookie.replace('"', ""))
    return cookie["__Secure-3PAPISID"].value


# SAPISID Hash reverse engineered by
# https://stackoverflow.com/a/32065323/5726546
def get_authorization(auth):
    sha_1 = sha1()
    unix_timestamp = str(int(time.time()))
    sha_1.update((unix_timestamp + " " + auth).encode("utf-8"))
    return "SAPISIDHASH " + unix_timestamp + "_" + sha_1.hexdigest()


def to_int(string):
    string = unicodedata.normalize("NFKD", string)
    number_string = re.sub(r"\D", "", string)
    try:
        int_value = locale.atoi(number_string)
    except ValueError:
        number_string = number_string.replace(",", "")
        int_value = int(number_string)
    return int_value


def sum_total_duration(item):
    if "tracks" not in item:
        return 0
    return sum(
        [
            track["duration_seconds"]
            if ("duration_seconds" in track and isinstance(track["duration_seconds"], int))
            else 0
            for track in item["tracks"]
        ]
    )
