"""Event wiring and initialization for Knowledge Explorer UI.

[feature: knowledge-ui, invariant: 1]
"""

import asyncio

import state
import render
import controls
import ws_handler


def _wrap_async(coro_fn):
    """Wrap an async handler so JS click events schedule the coroutine."""

    def handler(event):
        asyncio.ensure_future(coro_fn(event))

    return handler


async def init():
    """Initialize the Knowledge Explorer UI."""
    try:
        from js import document, window
        from pyodide.ffi import create_proxy
    except ImportError:
        return

    # Wire login button
    login_btn = document.getElementById("login-btn")
    if login_btn:
        login_btn.addEventListener(
            "click", create_proxy(_wrap_async(controls.on_login))
        )

    # Wire search button
    search_btn = document.getElementById("search-btn")
    if search_btn:
        search_btn.addEventListener(
            "click", create_proxy(_wrap_async(controls.on_search))
        )

    # Wire ingest button
    ingest_btn = document.getElementById("ingest-btn")
    if ingest_btn:
        ingest_btn.addEventListener(
            "click", create_proxy(_wrap_async(controls.on_ingest))
        )

    # Wire refresh button
    refresh_btn = document.getElementById("refresh-btn")
    if refresh_btn:
        refresh_btn.addEventListener(
            "click", create_proxy(_wrap_async(controls.on_refresh))
        )

    # Wire functor dropdown change
    functor_select = document.getElementById("ingest-functor")
    if functor_select:
        functor_select.addEventListener(
            "change", create_proxy(_wrap_async(controls.on_functor_change))
        )

    # Wire logout button
    logout_btn = document.getElementById("logout-btn")
    if logout_btn:
        logout_btn.addEventListener(
            "click", create_proxy(_wrap_async(controls.on_logout))
        )

    # Show splash while checking authentication
    render.render_status("Checking authentication...", "info")

    # Fetch OIDC config and set up login UI
    auth_splash = document.getElementById("auth-splash")
    oidc = await controls.fetch_oidc_config()
    if oidc:
        # Check for OIDC callback (?code=...)
        handled = await controls.handle_oidc_callback()
        if handled:
            return  # Already logged in via callback

        # Try to restore existing session (token revalidation on refresh)
        restored = await controls.try_restore_session()
        if restored:
            return  # Session restored silently

        # No valid session — hide splash, show OIDC login button, hide JWT form
        if auth_splash:
            auth_splash.style.display = "none"
        oidc_div = document.getElementById("oidc-login")
        jwt_div = document.getElementById("jwt-login")
        if oidc_div:
            oidc_div.style.display = "block"
        if jwt_div:
            jwt_div.style.display = "none"

        oidc_btn = document.getElementById("oidc-login-btn")
        if oidc_btn:
            oidc_btn.addEventListener(
                "click", create_proxy(_wrap_async(controls.on_oidc_login))
            )
    else:
        # No OIDC — hide splash, show JWT form (local/demo mode)
        if auth_splash:
            auth_splash.style.display = "none"
        jwt_div = document.getElementById("jwt-login")
        if jwt_div:
            jwt_div.style.display = "block"

    render.render_status("Knowledge Explorer ready. Please log in.", "info")

    # Auto-connect WebSocket if token exists
    token = state.get_token()
    if token:
        ws_scheme = "wss" if window.location.protocol == "https:" else "ws"
        ws_url = f"{ws_scheme}://{window.location.host}/ws"
        await ws_handler.connect(ws_url, token)

    # Listen for cross-tab logout via storage events
    def _on_storage_change(event):
        if event.key == "jwt_token" and not event.newValue:
            asyncio.ensure_future(controls.on_logout(None))

    try:
        window.addEventListener("storage", create_proxy(_on_storage_change))
    except Exception:
        pass


# Schedule async initialization
asyncio.ensure_future(init())
