"""Common logic for generating table widgets."""

import logging
from collections.abc import Callable
from typing import Any

from nicegui import events
from nicegui import ui

logger = logging.getLogger(__name__)


def _extract_row_id(args: Any) -> str | None:
    if isinstance(args, dict):
        if isinstance(args.get("row"), dict):
            row_id = args["row"].get("id")
            return str(row_id) if row_id is not None else None
        row_id = args.get("id")
        return str(row_id) if row_id is not None else None

    if isinstance(args, list):
        for value in args:
            if isinstance(value, dict):
                row_id = value.get("id")
                if row_id is not None:
                    return str(row_id)

    return None


def _bind_row_click_handler(
    table: Any,
    *,
    on_row_click_id: Callable[[str], None],
) -> None:
    def handle_row_click(event: events.GenericEventArguments) -> None:
        row_id = _extract_row_id(event.args)
        if row_id is None:
            return
        on_row_click_id(row_id)

    table.on("rowClick", handle_row_click)
    logger.debug("Row click handler bound to table")


def build_table(
    rows: list[dict[str, Any]],
    columns: list[dict[str, Any]],
    *,
    default_sort_by: str | None = None,
    default_descending: bool = False,
    classes: str = "app-table",
    on_row_click_id: Callable[[str], None] | None = None,
) -> Any:
    pagination: dict[str, Any] = {"rowsPerPage": 25}
    if default_sort_by is not None:
        pagination["sortBy"] = default_sort_by
        pagination["descending"] = default_descending

    table = (
        ui.table(
            rows=rows,
            columns=columns,
            row_key="id",
            pagination=pagination,
        )
        .classes(classes)
        .props('table-style="table-layout: fixed; width: 100%;"')
    )
    logger.info("Table built with %d rows and %d columns", len(rows), len(columns))
    if on_row_click_id is not None:
        _bind_row_click_handler(table, on_row_click_id=on_row_click_id)
    return table
