from PySide6.QtCore import QObject
from reactivex import Observable
from reactivex import operators as ops
from reactivex.subject import Subject, ReplaySubject

from clochette.framework.qt.Signal import InHollowSignal
from clochette.presentation.theme.ThemeService import ThemeService
from clochette.presentation.window.QWebBrowserWindow import QWebBrowserWindow


class BrowserFactory(QObject):
    """
    Factory for creating QWebBrowserWindow instances.
    QWebBrowserWindow needs to be created from the main thread, hence why this factory extends QObject
    and hence why it comes with signals.
    """

    _theme_service: ThemeService
    _browser_subject: Subject[QWebBrowserWindow]
    _request_browser: InHollowSignal

    def __init__(self, theme_service: ThemeService):
        super().__init__()
        self._theme_service = theme_service
        self._browser_subject = ReplaySubject(buffer_size=1)
        self._request_browser = InHollowSignal(self._on_request_browser)

    def _on_request_browser(self) -> None:
        """Called on main Qt thread via InHollowSignal. Creates browser and emits via OutSolidSignal."""
        browser = QWebBrowserWindow(self._theme_service)
        self._browser_subject.on_next(browser)

    def create_browser(self) -> Observable[QWebBrowserWindow]:
        browser_observable = self._browser_subject.pipe(ops.take(1))
        self._request_browser()
        return browser_observable
