import os
import logging
from nicegui import ui, app
import db
import auth as auth_module
import mail


@ui.page("/")
async def index():
    ui.navigate.to("/dashboard" if auth_module.is_authenticated() else "/login")


@ui.page("/login")
async def login_page():
    if auth_module.is_authenticated():
        ui.navigate.to("/dashboard")
        return

    # First-run: redirect to setup if no users exist yet
    count = await db.fetchval("SELECT COUNT(*) FROM user_account")
    if count == 0:
        ui.navigate.to("/setup")
        return

    _login_form()


@ui.page("/setup")
async def setup_page():
    """First-run setup: create the initial superadmin account."""
    count = await db.fetchval("SELECT COUNT(*) FROM user_account")
    if count > 0:
        ui.navigate.to("/login")
        return

    ui.colors(primary="#f15b25", secondary="#6fd3f2")
    with ui.column().classes("w-full h-screen items-center justify-center bg-gray-50"):
        with ui.card().classes("w-96 p-8 gap-2"):
            with ui.row().classes("items-center gap-3 mb-2"):
                ui.image("/images/icon.svg").classes("w-10 h-10")
                ui.label("Welcome to LEAF Portal").classes(
                    "text-xl font-bold text-gray-800"
                )

            ui.label("Create your superadmin account to get started.").classes(
                "text-sm text-gray-500 mb-4"
            )

            name = ui.input("Full name").classes("w-full")
            email = ui.input("Email").classes("w-full").props("type=email")
            pw1 = ui.input(
                "Password", password=True, password_toggle_button=True
            ).classes("w-full")
            pw2 = ui.input(
                "Confirm password", password=True, password_toggle_button=True
            ).classes("w-full")
            error = ui.label("").classes("text-red-500 text-sm")

            async def create():
                error.text = ""
                if not all([name.value, email.value, pw1.value, pw2.value]):
                    error.text = "All fields are required."
                    return
                if pw1.value != pw2.value:
                    error.text = "Passwords do not match."
                    return
                if len(pw1.value) < 8:
                    error.text = "Password must be at least 8 characters."
                    return
                try:
                    hashed = await auth_module.hash_password(pw1.value)
                    await db.execute(
                        """
                        INSERT INTO user_account (email, name, password_hash, is_superadmin)
                        VALUES ($1, $2, $3, true)
                        """,
                        email.value.lower().strip(),
                        name.value.strip(),
                        hashed,
                    )
                    ui.notify("Account created — please sign in.", color="positive")
                    ui.navigate.to("/login")
                except Exception as e:
                    error.text = f"Error: {e}"

            ui.button("Create account", on_click=create, icon="person_add").classes(
                "w-full mt-2"
            ).props("color=primary")


def _login_form():
    ui.colors(primary="#f15b25", secondary="#6fd3f2")
    with ui.column().classes("w-full h-screen items-center justify-center bg-gray-50"):
        with ui.card().classes("w-96 p-8 gap-2"):
            with ui.row().classes("items-center gap-3 mb-4"):
                ui.image("/images/icon.svg").classes("w-10 h-10")
                ui.label("LEAF Portal").classes("text-2xl font-bold text-gray-800")

            email = ui.input("Email").classes("w-full").props("type=email")
            password = ui.input(
                "Password", password=True, password_toggle_button=True
            ).classes("w-full")
            error = ui.label("").classes("text-red-500 text-sm")

            async def do_login():
                error.text = ""
                user = await auth_module.verify_login(email.value, password.value)
                if user:
                    app.storage.user["user"] = {
                        "id": str(user["id"]),
                        "email": user["email"],
                        "name": user["name"],
                        "is_superadmin": user["is_superadmin"],
                    }
                    ui.navigate.to("/dashboard")
                else:
                    error.text = "Invalid email or password."

            ui.button("Sign in", on_click=do_login, icon="login").classes(
                "w-full mt-2"
            ).props("color=primary")
            password.on("keydown.enter", do_login)
            ui.link("Forgot password?", "/forgot-password").classes(
                "text-sm text-gray-400 mt-1 self-end"
            )


@ui.page("/forgot-password")
async def forgot_password_page():
    if auth_module.is_authenticated():
        ui.navigate.to("/dashboard")
        return

    ui.colors(primary="#f15b25", secondary="#6fd3f2")
    with ui.column().classes("w-full h-screen items-center justify-center bg-gray-50"):
        with ui.card().classes("w-96 p-8 gap-2"):
            with ui.row().classes("items-center gap-3 mb-2"):
                ui.image("/images/icon.svg").classes("w-10 h-10")
                ui.label("Reset password").classes("text-xl font-bold text-gray-800")

            ui.label(
                "Enter your email and we will send you a reset link (valid 1 hour)."
            ).classes("text-sm text-gray-500 mb-2")

            email_input = ui.input("Email").classes("w-full").props("type=email")
            msg = ui.label("").classes("text-sm")

            async def request_reset():
                addr = email_input.value.lower().strip()
                if not addr:
                    msg.classes(replace="text-sm text-red-500")
                    msg.text = "Enter your email address."
                    return
                try:
                    token = await auth_module.create_reset_token(addr)
                    if token:
                        portal_url = os.environ.get(
                            "PORTAL_URL", "http://localhost:8081"
                        )
                        reset_link = f"{portal_url}/reset-password?token={token}"
                        await mail.send_email(
                            to=addr,
                            subject="LEAF Portal — password reset",
                            body=(
                                f"Click the link below to reset your password (valid for 1 hour):\n\n"
                                f"{reset_link}\n\n"
                                f"If the link does not work, go to {portal_url}/reset-password\n"
                                f"and enter this code manually:\n\n"
                                f"{token}\n\n"
                                f"If you did not request this, you can ignore this email."
                            ),
                        )
                except Exception:
                    logging.exception("Password reset email failed")
                msg.classes(replace="text-sm").style("color: #f15b25")
                msg.text = "If you are registered, you will receive an email."

            ui.button("Send reset link", on_click=request_reset, icon="send").classes(
                "w-full mt-2"
            ).props("color=primary")
            ui.link("Back to login", "/login").classes("text-sm text-gray-400 mt-1")


@ui.page("/reset-password")
async def reset_password_page(token: str = ""):
    if auth_module.is_authenticated():
        ui.navigate.to("/dashboard")
        return

    ui.colors(primary="#f15b25", secondary="#6fd3f2")
    with ui.column().classes("w-full h-screen items-center justify-center bg-gray-50"):
        with ui.card().classes("w-96 p-8 gap-2"):
            with ui.row().classes("items-center gap-3 mb-2"):
                ui.image("/images/icon.svg").classes("w-10 h-10")
                ui.label("Set new password").classes("text-xl font-bold text-gray-800")

            if not token:
                # URL parameter was stripped — let the user paste the token manually
                ui.label("Paste the reset code from your email:").classes(
                    "text-sm text-gray-500"
                )
                token_input = ui.input("Reset code").classes("w-full")
                error_lbl = ui.label("").classes("text-red-500 text-sm")

                def go():
                    v = token_input.value.strip()
                    if not v:
                        error_lbl.text = "Paste the reset code from your email."
                        return
                    ui.navigate.to(f"/reset-password?token={v}")

                ui.button("Continue", on_click=go, icon="arrow_forward").classes(
                    "w-full mt-2"
                ).props("color=primary")
                ui.link("Back to login", "/login").classes("text-sm text-gray-400 mt-1")
                return

            user_info = await auth_module.verify_reset_token(token)
            if not user_info:
                ui.label(
                    "This reset link is invalid or has already been used."
                ).classes("text-red-500 text-sm")
                ui.link("Request a new one", "/forgot-password").classes(
                    "text-sm text-gray-400 mt-1"
                )
                return

            ui.label(f"Resetting password for {user_info['email']}").classes(
                "text-sm text-gray-500 mb-2"
            )

            pw1 = ui.input(
                "New password", password=True, password_toggle_button=True
            ).classes("w-full")
            pw2 = ui.input(
                "Confirm password", password=True, password_toggle_button=True
            ).classes("w-full")
            error = ui.label("").classes("text-red-500 text-sm")

            async def save():
                error.text = ""
                if pw1.value != pw2.value:
                    error.text = "Passwords do not match."
                    return
                if len(pw1.value) < 8:
                    error.text = "Password must be at least 8 characters."
                    return
                await auth_module.consume_reset_token(
                    str(user_info["token_id"]),
                    str(user_info["id"]),
                    pw1.value,
                )
                ui.notify("Password updated. Please sign in.", color="positive")
                ui.navigate.to("/login")

            ui.button("Set password", on_click=save, icon="lock_reset").classes(
                "w-full mt-2"
            ).props("color=primary")
            pw1.on("keydown.enter", save)
