from queue import Queue

from loguru import logger
from pyos.EventTypes import ScrollChange, TextBoxChange, TextBoxSubmit, MouseClick, MouseScroll

from . import Keys
from .ContextUtils import get_text, get_cursor_index, get_text_length, scroll_left, scroll_right, scroll_up, scroll_down


def handle_text_box_input(ui_element: str, input_context, event, event_queue: Queue):
    text = get_text(input_context)
    key = event.key

    if 32 <= key <= 126:
        i = get_cursor_index(input_context)
        if get_text_length(input_context) >= 0:
            input_context["text"] = text[:i] + chr(key) + text[i:]
        else:
            input_context["text"] = chr(key)
        input_context["cursor_index"] = get_cursor_index(input_context) + 1
        event_queue.put(TextBoxChange(ui_element=ui_element))

    if key == Keys.BACKSPACE:
        i = get_cursor_index(input_context)
        if i > 0:
            input_context["text"] = text[:i - 1] + text[i:]
            input_context["cursor_index"] = get_cursor_index(input_context) - 1
            event_queue.put(TextBoxChange(ui_element=ui_element))

    if key == Keys.LEFT:
        if get_cursor_index(input_context) > 0:
            input_context["cursor_index"] = get_cursor_index(input_context) - 1

    elif key == Keys.RIGHT:
        if get_cursor_index(input_context) < get_text_length(input_context):
            input_context["cursor_index"] = get_cursor_index(input_context) + 1

    elif key == Keys.HOME:
        input_context["cursor_index"] = 0

    elif key == Keys.END:
        input_context["cursor_index"] = len(text)

    elif key == Keys.ENTER:
        input_context["cursor_index"] = len(text)
        event_queue.put(TextBoxSubmit(ui_element=ui_element))


def handle_scroll_list_input(ui_element: str, scroll_context, event, event_queue: Queue):
    if scroll_context.get("selected_item") is None:
        if event.key == Keys.UP:
            scroll_up(scroll_context)
        elif event.key == Keys.DOWN:
            scroll_down(scroll_context)
    else:
        menu_context = scroll_context.get("menu")
        if not menu_context:
            logger.warning("No menu context found")
            return
        if event.key == Keys.LEFT:
            scroll_left(menu_context)
        elif event.key == Keys.RIGHT:
            scroll_right(menu_context)

    event_queue.put(ScrollChange(ui_element))


def handle_scroll_list_mouse(ui_element, ctx, event, local_y, event_queue):
    """Handle mouse events for a ScrollList component."""
    if isinstance(event, MouseClick):
        rendered_start = ctx.get("_rendered_start", 0)
        clicked_index = rendered_start + local_y
        items = ctx.get("items", [])
        if 0 <= clicked_index < len(items):
            ctx["selected_index"] = clicked_index
            event_queue.put(ScrollChange(ui_element))
    elif isinstance(event, MouseScroll):
        if event.direction == "up":
            scroll_up(ctx)
        else:
            scroll_down(ctx)
        event_queue.put(ScrollChange(ui_element))


def handle_text_input_mouse(ui_element, ctx, event, local_y, event_queue):
    """Handle mouse events for a TextInput component."""
    if isinstance(event, MouseClick):
        label = ctx.get("label", "")
        # Label prefix is "Label: [" — label + ": [" = len(label) + 3
        prefix_len = len(label) + 3
        view_offset = ctx.get("view_offset", 0)
        text = get_text(ctx)
        text_col = event.x - prefix_len + view_offset
        text_col = max(0, min(text_col, len(text)))
        ctx["cursor_index"] = text_col
        event_queue.put(TextBoxChange(ui_element=ui_element))
