"""Punto di ingresso del frontend Brython: accesso, layout, navigazione."""
from browser import document, window

import api
import state
import ui
import views_admin
import views_home
import views_login
import views_plans
import views_registry
import views_schedule
import views_shifts
import views_workers
from ui import E

ROUTES = [
    ("Pianificazione", [
        ("home", "Cruscotto", views_home.render),
        ("piani", "Periodi e giri", views_plans.render),
        ("turni", "Calendario turni", views_schedule.render),
        ("report", "Report", views_schedule.render_report),
    ]),
    ("Configurazione", [
        ("lavoratori", "Lavoratori e regole", views_workers.render),
        ("anagrafiche", "Stanze e specialità", views_registry.render),
        ("operativita", "Operatività", views_shifts.render),
    ]),
    ("Piattaforma", [
        ("admin", "Enti e account", views_admin.render),
    ]),
]

VIEWS = {slug: fn for _, items in ROUTES for slug, _, fn in items}


def _change_org(event):
    """Cambia l'ente su cui si sta lavorando e ricarica i dati."""
    org_id = int(event.target.value)
    state.CURRENT["plan_id"] = None
    api.post(f"/orgs/{org_id}/select", {}, lambda _: state.reload(render))


def _org_selector():
    orgs = state.AUTH.get("organizations", [])
    if len(orgs) <= 1:
        nome = orgs[0]["name"] if orgs else "nessun ente"
        return E("div", nome, cls="org-current")
    scelta = E("select", onchange=_change_org, cls="org-select")
    for org in orgs:
        opzione = E("option", org["name"], value=str(org["id"]))
        if org["id"] == state.AUTH.get("org_id"):
            opzione.selected = True
        scelta <= opzione
    return scelta


def _change_password():
    attuale = E("input", type="password")
    nuova = E("input", type="password")
    esito = E("div", cls="login-error")

    def salva():
        api.post("/auth/change-password", {"current": attuale.value, "new": nuova.value},
                 lambda _: (ui.toast("Password aggiornata: rientra con quella nuova", "ok"),
                            window.location.reload()),
                 lambda msg: setattr(esito, "text", msg))
        return False        # la modale resta aperta finché il server non conferma

    ui.modal("Cambia password",
             E("div",
               E("div", E("label", "Password attuale"), attuale, cls="field"),
               E("div", E("label", "Nuova password"), nuova, cls="field"),
               esito),
             on_confirm=salva, confirm_label="Aggiorna")


def _logout():
    api.post("/auth/logout", {}, lambda _: window.location.reload())


def _sidebar():
    aside = E("aside", cls="sidebar")
    aside <= E("div", "RotaManager", E("small", "gestione turni"), cls="brand")
    aside <= E("div", E("label", "Ente"), _org_selector(), cls="org-box")
    nav = E("nav")
    for group, items in ROUTES:
        if group == "Piattaforma" and not state.is_admin():
            continue
        nav <= E("div", group, cls="nav-group")
        for slug, label, _ in items:
            nav <= E("a", label, href=f"#{slug}",
                     cls="active" if slug == state.CURRENT["route"] else None)
    nav <= E("div", "Aiuto", cls="nav-group")
    # il manuale è una pagina a sé servita dal backend: si apre in una scheda nuova
    # per non perdere il lavoro in corso nei form aperti
    nav <= E("a", "Manuale d'uso", href="/manuale", target="_blank", rel="noopener")
    aside <= nav
    utente = state.user()
    aside <= E("div",
               E("div", utente.get("name") or utente.get("email", ""), cls="who"),
               E("div", utente.get("email", ""), cls="who-mail"),
               None if state.can_edit() else ui.badge("sola lettura", "warn"),
               E("div",
                 ui.button("Password", _change_password, cls="mini"),
                 ui.button("Esci", _logout, cls="mini"),
                 cls="row-flex"),
               cls="sidebar-foot")
    return aside


def render():
    root = document["root"]
    root.clear()
    root <= _sidebar()
    main = E("main")
    root <= main
    route = state.CURRENT["route"]
    if route == "admin" and not state.is_admin():
        route = "home"
    view = VIEWS.get(route, views_home.render)
    try:
        view(main)
    except Exception as exc:            # una vista rotta non deve lasciare la pagina vuota
        main <= E("div", E("h2", "Errore nell'interfaccia"), E("pre", str(exc)), cls="panel")
        raise


def show_login(message=None):
    document["root"].clear()
    views_login.render(document["root"], message)


def _on_hash(ev=None):
    route = window.location.hash[1:] or "home"
    if route != state.CURRENT["route"]:
        state.CURRENT["route"] = route
        if state.AUTH.get("user"):
            render()


def _start(sessione):
    """Decide cosa mostrare in base allo stato della sessione."""
    if not sessione or not sessione.get("authenticated"):
        show_login()
        return
    if not sessione.get("organizations"):
        show_login("Nessun ente associato a questo account: contatta l'amministratore.")
        return
    state.reload(render)


state.set_rerender(render)
api.on_unauthorized = lambda: show_login("Sessione scaduta: accedi di nuovo.")
window.addEventListener("hashchange", _on_hash)
state.CURRENT["route"] = window.location.hash[1:] or "home"
api.get("/auth/me", _start)
