import os
from pathlib import Path
from nicegui import ui
from dotenv import set_key, find_dotenv
import db
import auth as auth_module
import layout


SETTING_GROUPS = [
    {
        "namespace": "smtp",
        "title": "Mail (SMTP)",
        "icon": "email",
        "fields": [
            {"key": "host", "label": "Host", "password": False},
            {"key": "port", "label": "Port", "password": False},
            {"key": "user", "label": "User", "password": False},
            {"key": "password", "label": "Password", "password": True},
            {"key": "from", "label": "From", "password": False},
        ],
    },
]


@ui.page("/admin/settings")
async def settings_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

    with layout.page("Settings"):
        await _db_setting_card()
        for group in SETTING_GROUPS:
            await _setting_group(group)


async def _db_setting_card() -> None:
    with ui.expansion("Database", icon="storage").classes("w-full"):
        host = ui.input("Host", value=os.environ.get("PGHOST", "")).classes("w-full")
        port = ui.input("Port", value=os.environ.get("PGPORT", "5432")).classes(
            "w-full"
        )
        user = ui.input("User", value=os.environ.get("PGUSER", "")).classes("w-full")
        password = ui.input(
            "Password",
            value=os.environ.get("PGPASSWORD", ""),
            password=True,
            password_toggle_button=True,
        ).classes("w-full")
        database = ui.input("Database", value=os.environ.get("PGDATABASE", "")).classes(
            "w-full"
        )
        status = ui.label("").classes("text-sm")

        async def save_db():
            try:
                await db.connect(
                    host=host.value,
                    port=int(port.value),
                    user=user.value,
                    password=password.value,
                    database=database.value,
                )
                env_file = find_dotenv() or str(Path.cwd() / ".env")
                set_key(env_file, "PGHOST", host.value)
                set_key(env_file, "PGPORT", port.value)
                set_key(env_file, "PGUSER", user.value)
                set_key(env_file, "PGPASSWORD", password.value)
                set_key(env_file, "PGDATABASE", database.value)
                status.classes("text-green-600", remove="text-red-500")
                status.text = "Reconnected and saved."
            except Exception as e:
                status.classes("text-red-500", remove="text-green-600")
                status.text = f"Error: {e}"

        with ui.row().classes("w-full justify-end mt-2"):
            ui.button("Save & reconnect", icon="sync", on_click=save_db).props(
                "color=primary"
            )


async def _setting_group(group: dict) -> None:
    namespace = group["namespace"]
    with ui.expansion(group["title"], icon=group["icon"]).classes("w-full"):
        inputs: dict[str, ui.input] = {}
        for field in group["fields"]:
            current = await db.get_setting(field["key"], namespace) or ""
            kwargs = {"label": field["label"], "value": current}
            if field["password"]:
                kwargs["password"] = True
                kwargs["password_toggle_button"] = True
            inp = ui.input(**kwargs).classes("w-full")
            inputs[field["key"]] = inp

        status = ui.label("").classes("text-sm")

        async def save(ns=namespace, inps=inputs, lbl=status):
            try:
                for k, inp in inps.items():
                    await db.set_setting(k, inp.value, ns)
                lbl.classes("text-green-600", remove="text-red-500")
                lbl.text = "Saved."
            except Exception as e:
                lbl.classes("text-red-500", remove="text-green-600")
                lbl.text = f"Error: {e}"

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