pragma ComponentBehavior: Bound

import QtQuick
import qs.Common
import qs.Modals.Common
import qs.Services
import qs.Widgets
import qs.Modules.Settings.Widgets

Item {
    id: root

    property string statusText: ""
    property bool statusIsError: false
    property bool operationPending: false
    property string pendingUsername: ""
    property string pendingPassword: ""
    property string pendingConfirm: ""
    property bool pendingAdmin: false
    property bool pendingGreeter: false

    function _resetForm() {
        pendingUsername = "";
        pendingPassword = "";
        pendingConfirm = "";
        pendingAdmin = false;
        pendingGreeter = false;
        usernameField.text = "";
        passwordField.text = "";
        confirmField.text = "";
    }

    function _passwordsMatch() {
        return pendingPassword.length > 0 && pendingPassword === pendingConfirm;
    }

    function _createCanProceed() {
        return !operationPending && UsersService.isValidUsername(pendingUsername) && !UsersService.userExists(pendingUsername) && _passwordsMatch();
    }

    Connections {
        target: UsersService
        function onOperationCompleted(op, username, success, message) {
            root.operationPending = false;
            root.statusIsError = !success;
            if (success) {
                root.statusText = message + (username ? (" — " + username) : "");
                if (op === "create")
                    root._resetForm();
            } else {
                root.statusText = (username ? (username + ": ") : "") + message;
            }
        }
    }

    ConfirmModal {
        id: deleteUserConfirm
    }

    ConfirmModal {
        id: adminToggleConfirm
    }

    ConfirmModal {
        id: greeterToggleConfirm
    }

    DankFlickable {
        anchors.fill: parent
        clip: true
        contentHeight: mainColumn.height + Theme.spacingXL
        contentWidth: width

        Column {
            id: mainColumn
            topPadding: 4
            width: Math.min(600, parent.width - Theme.spacingL * 2)
            anchors.horizontalCenter: parent.horizontalCenter
            spacing: Theme.spacingXL

            StyledText {
                width: parent.width
                visible: !PolkitService.polkitAvailable
                text: I18n.tr("Polkit integration is disabled. User management requires Polkit to elevate privileges.")
                font.pixelSize: Theme.fontSizeMedium
                color: Theme.error
                wrapMode: Text.WordWrap
            }

            SettingsCard {
                width: parent.width
                iconName: "group"
                title: I18n.tr("Existing Users")
                settingKey: "usersList"
                visible: PolkitService.polkitAvailable

                Row {
                    width: parent.width
                    spacing: Theme.spacingS

                    StyledText {
                        text: I18n.tr("Administrator group:")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.surfaceVariantText
                        anchors.verticalCenter: parent.verticalCenter
                    }

                    StyledText {
                        text: UsersService.adminGroup
                        font.pixelSize: Theme.fontSizeSmall
                        font.weight: Font.Medium
                        color: Theme.surfaceText
                        anchors.verticalCenter: parent.verticalCenter
                    }

                    Item {
                        width: Theme.spacingM
                        height: 1
                    }

                    StyledText {
                        text: I18n.tr("Greeter group:")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.surfaceVariantText
                        anchors.verticalCenter: parent.verticalCenter
                    }

                    StyledText {
                        text: UsersService.greeterGroup
                        font.pixelSize: Theme.fontSizeSmall
                        font.weight: Font.Medium
                        color: Theme.surfaceText
                        anchors.verticalCenter: parent.verticalCenter
                    }

                    Item {
                        width: Theme.spacingM
                        height: 1
                    }

                    StyledText {
                        text: UsersService.refreshing ? I18n.tr("Refreshing...") : ""
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.surfaceVariantText
                        anchors.verticalCenter: parent.verticalCenter
                    }
                }

                StyledText {
                    width: parent.width
                    text: I18n.tr("Greeter group members can sync their login-screen theme with dms-greeter sync --profile after logging out and back in.")
                    font.pixelSize: Theme.fontSizeSmall
                    color: Theme.surfaceVariantText
                    wrapMode: Text.Wrap
                }

                Repeater {
                    model: UsersService.users

                    Rectangle {
                        id: userRow
                        required property var modelData
                        width: parent.width
                        height: Math.max(48, rowContent.implicitHeight + Theme.spacingS * 2)
                        radius: Theme.cornerRadius
                        color: Theme.surfaceContainerHighest

                        readonly property bool isLastAdmin: modelData.isAdmin && UsersService.adminMembers.length <= 1

                        Row {
                            id: rowContent
                            anchors.fill: parent
                            anchors.margins: Theme.spacingM
                            spacing: Theme.spacingM

                            DankIcon {
                                name: "account_circle"
                                size: Theme.iconSize
                                color: Theme.primary
                                anchors.verticalCenter: parent.verticalCenter
                            }

                            Column {
                                width: parent.width - Theme.iconSize - actionButtons.width - Theme.spacingM * 3
                                spacing: Theme.spacingXXS
                                anchors.verticalCenter: parent.verticalCenter

                                Row {
                                    spacing: Theme.spacingS

                                    StyledText {
                                        text: userRow.modelData.username
                                        font.pixelSize: Theme.fontSizeMedium
                                        font.weight: Font.Medium
                                        color: Theme.surfaceText
                                        anchors.verticalCenter: parent.verticalCenter
                                    }

                                    Rectangle {
                                        visible: userRow.modelData.isAdmin
                                        width: adminChipText.implicitWidth + Theme.spacingS * 2
                                        height: adminChipText.implicitHeight + Theme.spacingXS * 2
                                        radius: Theme.cornerRadius
                                        color: Theme.withAlpha(Theme.primary, 0.15)
                                        anchors.verticalCenter: parent.verticalCenter

                                        StyledText {
                                            id: adminChipText
                                            anchors.centerIn: parent
                                            text: I18n.tr("admin")
                                            font.pixelSize: Theme.fontSizeSmall
                                            color: Theme.primary
                                            font.weight: Font.Medium
                                        }
                                    }

                                    Rectangle {
                                        visible: userRow.modelData.isGreeter
                                        width: greeterChipText.implicitWidth + Theme.spacingS * 2
                                        height: greeterChipText.implicitHeight + Theme.spacingXS * 2
                                        radius: Theme.cornerRadius
                                        color: Theme.withAlpha(Theme.secondary, 0.15)
                                        anchors.verticalCenter: parent.verticalCenter

                                        StyledText {
                                            id: greeterChipText
                                            anchors.centerIn: parent
                                            text: I18n.tr("Greeter")
                                            font.pixelSize: Theme.fontSizeSmall
                                            color: Theme.secondary
                                            font.weight: Font.Medium
                                        }
                                    }
                                }

                                StyledText {
                                    text: userRow.modelData.gecos && userRow.modelData.gecos.length > 0 ? userRow.modelData.gecos + " · UID " + userRow.modelData.uid : "UID " + userRow.modelData.uid
                                    font.pixelSize: Theme.fontSizeSmall
                                    color: Theme.surfaceVariantText
                                    elide: Text.ElideRight
                                    width: parent.width
                                }
                            }

                            Row {
                                id: actionButtons
                                spacing: Theme.spacingS
                                anchors.verticalCenter: parent.verticalCenter

                                DankActionButton {
                                    id: greeterToggleBtn
                                    readonly property bool actionBlocked: root.operationPending
                                    buttonSize: 36
                                    iconSize: 20
                                    iconName: userRow.modelData.isGreeter ? "login" : "how_to_reg"
                                    iconColor: userRow.modelData.isGreeter ? Theme.secondary : Theme.surfaceVariantText
                                    opacity: actionBlocked ? 0.4 : 1.0
                                    tooltipText: userRow.modelData.isGreeter ? I18n.tr("Remove greeter login access") : I18n.tr("Allow greeter login access")
                                    tooltipSide: "left"
                                    onClicked: {
                                        if (actionBlocked)
                                            return;
                                        const enableGreeter = !userRow.modelData.isGreeter;
                                        greeterToggleConfirm.showWithOptions({
                                            title: enableGreeter ? I18n.tr("Allow greeter access?") : I18n.tr("Remove greeter access?"),
                                            message: enableGreeter ? I18n.tr("Add \"%1\" to the %2 group? They must log out and back in, then run dms-greeter sync --profile to publish their login-screen theme.").arg(userRow.modelData.username).arg(UsersService.greeterGroup) : I18n.tr("Remove \"%1\" from the %2 group?").arg(userRow.modelData.username).arg(UsersService.greeterGroup),
                                            confirmText: enableGreeter ? I18n.tr("Allow") : I18n.tr("Remove"),
                                            confirmColor: Theme.primary,
                                            onConfirm: () => {
                                                root.operationPending = true;
                                                root.statusText = "";
                                                UsersService.setGreeterAccess(userRow.modelData.username, enableGreeter, null);
                                            }
                                        });
                                    }
                                }

                                DankActionButton {
                                    id: adminToggleBtn
                                    readonly property bool actionBlocked: root.operationPending || (userRow.isLastAdmin && userRow.modelData.isAdmin)
                                    buttonSize: 36
                                    iconSize: 20
                                    iconName: userRow.modelData.isAdmin ? "shield_person" : "shield"
                                    iconColor: userRow.modelData.isAdmin ? Theme.primary : Theme.surfaceVariantText
                                    opacity: actionBlocked ? 0.4 : 1.0
                                    tooltipText: (userRow.isLastAdmin && userRow.modelData.isAdmin) ? I18n.tr("Cannot remove the only administrator") : (userRow.modelData.isAdmin ? I18n.tr("Remove admin") : I18n.tr("Make admin"))
                                    tooltipSide: "left"
                                    onClicked: {
                                        if (actionBlocked)
                                            return;
                                        const makeAdmin = !userRow.modelData.isAdmin;
                                        adminToggleConfirm.showWithOptions({
                                            title: makeAdmin ? I18n.tr("Make admin") : I18n.tr("Remove admin"),
                                            message: makeAdmin ? I18n.tr("Add \"%1\" to the %2 group?").arg(userRow.modelData.username).arg(UsersService.adminGroup) : I18n.tr("Remove \"%1\" from the %2 group?").arg(userRow.modelData.username).arg(UsersService.adminGroup),
                                            confirmText: makeAdmin ? I18n.tr("Grant") : I18n.tr("Remove"),
                                            confirmColor: Theme.primary,
                                            onConfirm: () => {
                                                root.operationPending = true;
                                                root.statusText = "";
                                                UsersService.setAdmin(userRow.modelData.username, makeAdmin, null);
                                            }
                                        });
                                    }
                                }

                                DankActionButton {
                                    id: deleteBtn
                                    readonly property bool actionBlocked: root.operationPending || !UsersService.canDelete(userRow.modelData.username)
                                    buttonSize: 36
                                    iconSize: 20
                                    iconName: "delete"
                                    iconColor: Theme.error
                                    opacity: actionBlocked ? 0.4 : 1.0
                                    tooltipText: userRow.isLastAdmin ? I18n.tr("Cannot delete the only administrator") : I18n.tr("Delete user")
                                    tooltipSide: "left"
                                    onClicked: {
                                        if (actionBlocked)
                                            return;
                                        deleteUserConfirm.showWithOptions({
                                            title: I18n.tr("Delete user"),
                                            message: I18n.tr("Delete \"%1\" and remove the home directory? This cannot be undone.").arg(userRow.modelData.username),
                                            confirmText: I18n.tr("Delete"),
                                            confirmColor: Theme.primary,
                                            onConfirm: () => {
                                                root.operationPending = true;
                                                root.statusText = "";
                                                UsersService.deleteUser(userRow.modelData.username, null);
                                            }
                                        });
                                    }
                                }
                            }
                        }
                    }
                }

                StyledText {
                    width: parent.width
                    visible: UsersService.users.length === 0 && !UsersService.refreshing
                    text: I18n.tr("No human user accounts found.")
                    font.pixelSize: Theme.fontSizeSmall
                    color: Theme.surfaceVariantText
                }
            }

            SettingsCard {
                width: parent.width
                iconName: "person_add"
                title: I18n.tr("Create User")
                settingKey: "createUser"
                visible: PolkitService.polkitAvailable

                Column {
                    width: parent.width
                    spacing: Theme.spacingXS

                    StyledText {
                        text: I18n.tr("Username")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.surfaceVariantText
                    }

                    DankTextField {
                        id: usernameField
                        width: parent.width
                        placeholderText: I18n.tr("e.g. alice")
                        backgroundColor: Theme.surfaceContainerHighest
                        normalBorderColor: usernameInvalid ? Theme.error : Theme.outlineMedium
                        focusedBorderColor: usernameInvalid ? Theme.error : Theme.primary

                        readonly property bool usernameInvalid: text.length > 0 && (!UsersService.isValidUsername(text) || UsersService.userExists(text))

                        onTextEdited: {
                            root.pendingUsername = text.trim();
                        }
                    }

                    StyledText {
                        width: parent.width
                        visible: usernameField.text.length > 0 && !UsersService.isValidUsername(usernameField.text)
                        text: I18n.tr("Username must start with a lowercase letter or underscore and contain only lowercase letters, digits, hyphens, or underscores.")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.error
                        wrapMode: Text.WordWrap
                    }

                    StyledText {
                        width: parent.width
                        visible: usernameField.text.length > 0 && UsersService.isValidUsername(usernameField.text) && UsersService.userExists(usernameField.text)
                        text: I18n.tr("A user with that name already exists.")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.error
                        wrapMode: Text.WordWrap
                    }
                }

                Column {
                    width: parent.width
                    spacing: Theme.spacingXS

                    StyledText {
                        text: I18n.tr("Password")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.surfaceVariantText
                    }

                    DankTextField {
                        id: passwordField
                        width: parent.width
                        placeholderText: I18n.tr("Set initial password")
                        echoMode: TextInput.Password
                        showPasswordToggle: true
                        backgroundColor: Theme.surfaceContainerHighest
                        normalBorderColor: Theme.outlineMedium
                        focusedBorderColor: Theme.primary
                        onTextEdited: root.pendingPassword = text
                    }
                }

                Column {
                    width: parent.width
                    spacing: Theme.spacingXS

                    StyledText {
                        text: I18n.tr("Confirm password")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.surfaceVariantText
                    }

                    DankTextField {
                        id: confirmField
                        width: parent.width
                        placeholderText: I18n.tr("Re-enter password")
                        echoMode: TextInput.Password
                        showPasswordToggle: true
                        backgroundColor: Theme.surfaceContainerHighest
                        normalBorderColor: confirmMismatch ? Theme.error : Theme.outlineMedium
                        focusedBorderColor: confirmMismatch ? Theme.error : Theme.primary

                        readonly property bool confirmMismatch: text.length > 0 && text !== passwordField.text

                        onTextEdited: root.pendingConfirm = text
                    }

                    StyledText {
                        width: parent.width
                        visible: confirmField.text.length > 0 && confirmField.text !== passwordField.text
                        text: I18n.tr("Passwords do not match.")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.error
                    }
                }

                SettingsToggleRow {
                    settingKey: "createUserAdmin"
                    tags: ["user", "admin", "sudo", "wheel"]
                    text: I18n.tr("Grant administrator privileges")
                    description: I18n.tr("Add the new user to the %1 group so they can use sudo.").arg(UsersService.adminGroup)
                    checked: root.pendingAdmin
                    onToggled: checked => root.pendingAdmin = checked
                }

                SettingsToggleRow {
                    settingKey: "createUserGreeter"
                    tags: ["user", "greeter", "login", "sync"]
                    text: I18n.tr("Allow greeter login access")
                    description: I18n.tr("Add the new user to the %1 group so they can run dms-greeter sync --profile.").arg(UsersService.greeterGroup)
                    checked: root.pendingGreeter
                    onToggled: checked => root.pendingGreeter = checked
                }

                Row {
                    width: parent.width
                    spacing: Theme.spacingM

                    DankButton {
                        text: root.operationPending ? I18n.tr("Working...") : I18n.tr("Create User")
                        iconName: "person_add"
                        backgroundColor: Theme.primary
                        textColor: Theme.primaryText
                        enabled: root._createCanProceed()
                        onClicked: {
                            if (!root._createCanProceed())
                                return;
                            root.operationPending = true;
                            root.statusText = "";
                            UsersService.createUser(root.pendingUsername, root.pendingPassword, root.pendingAdmin, root.pendingGreeter, null);
                        }
                    }

                    StyledText {
                        anchors.verticalCenter: parent.verticalCenter
                        text: root.statusText
                        color: root.statusIsError ? Theme.error : Theme.primary
                        font.pixelSize: Theme.fontSizeSmall
                        wrapMode: Text.WordWrap
                        width: parent.width - parent.children[0].width - Theme.spacingM
                    }
                }
            }
        }
    }
}
