// The authentication prompt.
//
// Deliberately a Panama surface rather than the compositor's stock agent: this
// is the window that asks for the password to everything, and it was the one
// window on the desktop that looked like it belonged to something else.
//
// Two things here are security, not styling. It takes EXCLUSIVE keyboard focus,
// so keystrokes cannot reach the window underneath while a password is being
// typed. And the field is cleared on every exit path, including the ones nobody
// plans for.

import Quickshell
import Quickshell.Wayland
import QtQuick
import qs.config
import qs.services
import qs.modules.settings

PanelWindow {
    id: root

    visible: Polkit.active
    color: "transparent"

    anchors { top: true; bottom: true; left: true; right: true }
    exclusiveZone: 0

    WlrLayershell.namespace: "qs-polkit"
    WlrLayershell.layer: WlrLayer.Overlay
    // Exclusive, not OnDemand: a password prompt that lets keystrokes through
    // to whatever is behind it is a keylogger with extra steps.
    WlrLayershell.keyboardFocus: Polkit.active
        ? WlrKeyboardFocus.Exclusive
        : WlrKeyboardFocus.None

    onVisibleChanged: {
        if (root.visible) {
            field.text = "";
            field.forceActiveFocus();
        } else {
            field.text = "";
        }
    }

    // Dims what is behind, and swallows clicks so nothing outside the dialog
    // can be operated while it is waiting.
    Rectangle {
        anchors.fill: parent
        color: Theme.alpha(Theme.bgDark, Theme.overlayAlpha)

        MouseArea {
            anchors.fill: parent
            // Clicking outside does nothing on purpose. Dismissing an
            // authentication request by misclick, and having the thing that
            // asked report a mysterious failure, is worse than an explicit
            // Cancel.
            hoverEnabled: true
        }
    }

    Rectangle {
        id: dialog

        anchors.centerIn: parent
        width: 420
        implicitHeight: layout.implicitHeight + 44
        radius: Theme.popoverRadius
        color: Theme.alpha(Theme.bgPopover, Theme.popoverAlpha)
        border.width: 1
        border.color: Theme.alpha(Theme.fg, 0.1)

        Column {
            id: layout
            anchors.centerIn: parent
            width: parent.width - 44
            spacing: 14

            Text {
                width: parent.width
                text: "Authentication required"
                color: Theme.fg
                font.family: Theme.fontFamily
                font.pixelSize: Theme.fontSizeLarge
                font.weight: Font.DemiBold
                wrapMode: Text.WordWrap
            }

            Text {
                width: parent.width
                text: Polkit.message
                color: Theme.fgDim
                font.family: Theme.fontFamily
                font.pixelSize: Theme.fontSize
                wrapMode: Text.WordWrap
            }

            // The caller's stated reason, when panama-sudo passed one.
            // Untrusted commentary from an unprivileged process, so it is
            // labeled as a claim and drawn beside polkitd's message above --
            // never in place of it. The real action text is the trust anchor.
            Column {
                width: parent.width
                visible: Polkit.statedReason !== ""
                spacing: 2

                Text {
                    text: "Stated reason (unverified)"
                    color: Theme.fgMuted
                    font.family: Theme.fontFamily
                    font.pixelSize: Theme.fontSizeSmall
                    font.weight: Font.DemiBold
                }

                Text {
                    width: parent.width
                    text: Polkit.statedReason
                    color: Theme.fgDim
                    font.family: Theme.fontFamily
                    font.pixelSize: Theme.fontSize
                    font.italic: true
                    wrapMode: Text.WordWrap
                }
            }

            Text {
                width: parent.width
                visible: Polkit.users.length > 1
                text: "Authenticating as " + Polkit.chosenUser
                color: Theme.fgMuted
                font.family: Theme.fontFamily
                font.pixelSize: Theme.fontSizeSmall
            }

            PasswordField {
                id: field
                width: parent.width
                placeholder: "Password"
                enabled: !Polkit.authenticating
                onAccepted: {
                    if (field.text !== "")
                        Polkit.submit(field.text);
                    field.text = "";
                }
            }

            Text {
                width: parent.width
                visible: Polkit.failureText !== ""
                text: Polkit.failureText
                color: Theme.danger
                font.family: Theme.fontFamily
                font.pixelSize: Theme.fontSizeSmall
                wrapMode: Text.WordWrap
            }

            Row {
                anchors.right: parent.right
                spacing: 8

                SettingsButton {
                    text: "Cancel"
                    onClicked: Polkit.cancel()
                }

                SettingsButton {
                    text: Polkit.authenticating ? "Checking…" : "Authenticate"
                    tone: "accent"
                    enabled: !Polkit.authenticating
                    onClicked: {
                        if (field.text !== "")
                            Polkit.submit(field.text);
                        field.text = "";
                    }
                }
            }
        }
    }

    // Escape cancels, which is what every other dialog on this desktop does.
    Item {
        anchors.fill: parent
        focus: true
        Keys.onEscapePressed: Polkit.cancel()
    }
}
