from nicegui import ui
import db
import auth as auth_module
import layout


@ui.page("/admin/organisations")
async def organisations_page():
    await auth_module.sync_session()
    if not auth_module.is_authenticated():
        ui.navigate.to("/login")
        return
    if not auth_module.is_superadmin():
        ui.navigate.to("/dashboard")
        return

    rows = await db.fetch(
        """
        SELECT i.id, i.name, i.created_at,
               COUNT(DISTINCT d.id)  AS n_departments,
               COUNT(DISTINCT ui.user_id) AS n_members
        FROM organisation i
        LEFT JOIN department d   ON d.organisation_id = i.id
        LEFT JOIN user_organisation ui ON ui.organisation_id = i.id
        GROUP BY i.id
        ORDER BY i.name
        """
    )

    with layout.page("Organisations"):
        # ── toolbar ─────────────────────────────────────────────────────────
        with ui.row().classes("w-full items-center justify-between -mt-2"):
            ui.label(f"{len(rows)} organisation(s)").classes("text-sm text-gray-500")
            ui.button(
                "Add organisation", icon="add", on_click=lambda: add_dialog.open()
            ).props("color=primary")

        # ── table ────────────────────────────────────────────────────────────
        columns = [
            {"name": "name", "label": "Name", "field": "name", "align": "left"},
            {
                "name": "n_departments",
                "label": "Departments",
                "field": "n_departments",
                "align": "center",
            },
            {
                "name": "n_members",
                "label": "Members",
                "field": "n_members",
                "align": "center",
            },
            {
                "name": "created_at",
                "label": "Created",
                "field": "created_at",
                "align": "left",
            },
            {"name": "actions", "label": "", "field": "actions", "align": "right"},
        ]
        row_data = [
            {
                "id": str(r["id"]),
                "name": r["name"],
                "n_departments": r["n_departments"],
                "n_members": r["n_members"],
                "created_at": r["created_at"].strftime("%Y-%m-%d"),
            }
            for r in rows
        ]

        table = ui.table(columns=columns, rows=row_data, row_key="id").classes("w-full")
        with table.add_slot("body-cell-actions"):
            with table.cell():
                ui.button(icon="edit").props("flat round dense color=grey").on(
                    "click",
                    js_handler="() => emit(props.row)",
                    handler=lambda e: _rename_dialog(e.args["id"], e.args["name"]),
                )
                ui.button(icon="delete").props("flat round dense color=negative").on(
                    "click",
                    js_handler="() => emit(props.row)",
                    handler=lambda e: _confirm_delete(e.args["id"], e.args["name"]),
                )

        # ── add dialog ───────────────────────────────────────────────────────
        with ui.dialog() as add_dialog, ui.card().classes("w-80 p-6 gap-4"):
            ui.label("New organisation").classes("text-lg font-semibold")
            name_input = (
                ui.input("Name", placeholder="e.g. UNLOCK")
                .on("keydown.enter", lambda e: save())
                .classes("w-full")
            )
            error = ui.label("").classes("text-red-500 text-sm")

            async def save():
                error.text = ""
                val = name_input.value.strip()
                if not val:
                    error.text = "Name is required."
                    return
                try:
                    await db.execute("INSERT INTO organisation (name) VALUES ($1)", val)
                    add_dialog.close()
                    ui.navigate.to("/admin/organisations")
                except Exception as e:
                    error.text = f"Error: {e}"

            with ui.row().classes("w-full justify-end gap-2 mt-2"):
                ui.button("Cancel", on_click=add_dialog.close).props("flat")
                ui.button("Save", on_click=save).props("color=primary")


def _rename_dialog(organisation_id: str, current_name: str) -> None:
    with ui.dialog() as dlg, ui.card().classes("w-80 p-6 gap-4"):
        ui.label("Rename organisation").classes("text-lg font-semibold")
        name_input = (
            ui.input("Name", value=current_name)
            .on("keydown.enter", lambda e: save())
            .classes("w-full")
        )
        error = ui.label("").classes("text-red-500 text-sm")

        async def save():
            error.text = ""
            val = name_input.value.strip()
            if not val:
                error.text = "Name is required."
                return
            try:
                await db.execute(
                    "UPDATE organisation SET name = $1 WHERE id = $2",
                    val,
                    organisation_id,
                )
                dlg.close()
                ui.navigate.to("/admin/organisations")
            except Exception as e:
                error.text = f"Error: {e}"

        with ui.row().classes("w-full justify-end gap-2 mt-2"):
            ui.button("Cancel", on_click=dlg.close).props("flat")
            ui.button("Save", on_click=save).props("color=primary")

    dlg.open()


def _confirm_delete(organisation_id: str, name: str) -> None:
    with ui.dialog() as dlg, ui.card().classes("p-6 gap-4"):
        ui.label(f'Delete "{name}"?').classes("text-lg font-semibold")
        ui.label("This will also delete all departments in this organisation.").classes(
            "text-sm text-gray-500"
        )

        async def confirm():
            try:
                await db.execute(
                    "DELETE FROM organisation WHERE id = $1", organisation_id
                )
                dlg.close()
                ui.navigate.to("/admin/organisations")
            except Exception as e:
                ui.notify(f"Error: {e}", color="negative")

        with ui.row().classes("w-full justify-end gap-2"):
            ui.button("Cancel", on_click=dlg.close).props("flat")
            ui.button("Delete", on_click=confirm).props("color=negative")

    dlg.open()
