from functools import wraps

from ytmusicapi.navigation import *


def parse_menu_playlists(data, result):
    menu_items = nav(data, MENU_ITEMS, True)
    if menu_items is None:
        return
    watch_menu = find_objects_by_key(menu_items, MNIR)
    for item in [_x[MNIR] for _x in watch_menu]:
        icon = nav(item, ICON_TYPE)
        if icon == "MUSIC_SHUFFLE":
            watch_key = "shuffleId"
        elif icon == "MIX":
            watch_key = "radioId"
        else:
            continue

        watch_id = nav(item, ["navigationEndpoint", "watchPlaylistEndpoint", "playlistId"], True)
        if not watch_id:
            watch_id = nav(item, ["navigationEndpoint", "watchEndpoint", "playlistId"], True)
        if watch_id:
            result[watch_key] = watch_id


def get_item_text(item, index, run_index=0, none_if_absent=False):
    column = get_flex_column_item(item, index)
    if not column:
        return None
    if none_if_absent and len(column["text"]["runs"]) < run_index + 1:
        return None
    return column["text"]["runs"][run_index]["text"]


def get_flex_column_item(item, index):
    if (
        len(item["flexColumns"]) <= index
        or "text" not in item["flexColumns"][index]["musicResponsiveListItemFlexColumnRenderer"]
        or "runs" not in item["flexColumns"][index]["musicResponsiveListItemFlexColumnRenderer"]["text"]
    ):
        return None

    return item["flexColumns"][index]["musicResponsiveListItemFlexColumnRenderer"]


def get_fixed_column_item(item, index):
    if (
        "text" not in item["fixedColumns"][index]["musicResponsiveListItemFixedColumnRenderer"]
        or "runs" not in item["fixedColumns"][index]["musicResponsiveListItemFixedColumnRenderer"]["text"]
    ):
        return None

    return item["fixedColumns"][index]["musicResponsiveListItemFixedColumnRenderer"]


def get_dot_separator_index(runs):
    try:
        index = runs.index({"text": " • "})
    except ValueError:
        index = len(runs)

    return index


def parse_duration(duration):
    # duration may be falsy or a single space: ' '
    if not duration or not duration.strip():
        return duration
    duration_split = duration.strip().split(":")
    for d in duration_split:
        if not d.isdigit():  # For e.g: "2,343"
            return None
    mapped_increments = zip([1, 60, 3600], reversed(duration_split))
    seconds = sum(multiplier * int(time) for multiplier, time in mapped_increments)
    return seconds


def i18n(method):
    @wraps(method)
    def _impl(self, *method_args, **method_kwargs):
        method.__globals__["_"] = self.lang.gettext
        return method(self, *method_args, **method_kwargs)

    return _impl


def parse_id_name(sub_run):
    return {
        "id": nav(sub_run, NAVIGATION_BROWSE_ID, True),
        "name": nav(sub_run, ["text"], True),
    }
