"""Minimal bridge between Tkinter and an external asyncio loop."""

import asyncio
from typing import Callable


class AsyncRunner:
    """Run coroutines on a background loop and marshal results back to Tk."""

    def __init__(self, tk_root, loop: asyncio.AbstractEventLoop):
        """Store the Tk root widget and the loop used for background work."""
        self.tk = tk_root
        self.loop = loop

    def run(self, awaitable, on_ok: Callable, on_err: Callable, busy=None, message: str | None = None):
        """Schedule an awaitable and optionally show a busy indicator."""
        if busy:
            busy.show(message or "Lavoro in corso...")
        fut = asyncio.run_coroutine_threadsafe(awaitable, self.loop)
        self._poll(fut, on_ok, on_err, busy)

    def _poll(self, fut, on_ok, on_err, busy):
        """Poll the future until completion and invoke the proper callback."""
        if fut.done():
            if busy:
                busy.hide()
            try:
                res = fut.result()
                on_ok(res)
            except Exception as ex:
                on_err(ex)
            return
        self.tk.after(50, lambda: self._poll(fut, on_ok, on_err, busy))
