from typing import Any, List, Optional

from loguru import logger


def get_fixed_size(context):
    return context.get("fixed_size", 0)


def get_text(context):
    return context.get("text", "")


def move_menu_left(context):
    selected_index = context.get("selected_menu_index", 0)

    context["selected_menu_index"] = (selected_index - 1) % len(context["items"])


def move_menu_right(context):
    selected_index = context.get("selected_menu_index", 0)

    context["selected_menu_index"] = (selected_index + 1) % len(context["items"])


def get_cursor_index(context):
    return context.get("cursor_index", 0)


def get_text_length(context):
    if "text" in context:
        return len(context["text"])
    else:
        return -1


def get_x(context):
    return context.get("x", 0)


def scroll_up(context):
    index = context.get("selected_index", 0)
    new_index = max(0, index - 1)
    context["selected_index"] = new_index


def get_items_list(context) -> List:
    return context.get("items", [])


def scroll_down(context):
    index = context.get("selected_index", 0)
    new_index = max(0, index)
    new_index = min(get_num_lines(context) - 1, new_index + 1)
    context["selected_index"] = new_index


def scroll_to_top(context):
    context["selected_index"] = 0


def scroll_to_bottom(context):
    context["selected_index"] = get_num_lines(context) - 1


def scroll_left(context):
    items_len = len(context["items"])
    selected_index = context.get("selected_index", 0)
    index = (selected_index - 1) % items_len
    context["selected_index"] = index


def scroll_right(context):
    items_len = len(context["items"])
    selected_index = context.get("selected_index", 0)
    index = (selected_index + 1) % items_len
    context["selected_index"] = index


def is_hidden(context):
    return context.get("hidden", False)


def get_num_lines(context) -> int:
    """bit of a hack, some components work directly on items,
    some generate lines as an intermediary step for things like multiline text"""
    if "lines" in context:
        return len(context["lines"])
    else:
        return len(context.get("items", []))


def get_num_items(context) -> int:
    return len(context.get("items", []))


def get_selected_item(context) -> Any:
    return context.get("selected_item", None)


def get_selected_item_from_index_map(context) -> Optional[Any]:
    line_ids = context.get("line_ids")
    if not line_ids:
        return None
    idx = int(context.get("selected_index", 0) or 0)
    if 0 <= idx < len(line_ids):
        return line_ids[idx]
    return None


def get_items_len(context) -> int:
    items = context.get("items", None)

    if items is None:
        return None
    else:
        return len(items)
