// SPDX-FileCopyrightText: 2022 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL

import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts

import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
import org.kde.kirigamiaddons.delegates as Delegates
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
import org.kde.kitemmodels

import org.kde.neochat

FormCard.FormCardPage {
    id: root

    property NeoChatRoom room

    title: i18nc('@title:window', 'Permissions')

    readonly property PowerLevelModel powerLevelModel: PowerLevelModel {
        showMute: false
    }

    readonly property PermissionsModel permissionsModel: PermissionsModel {
        room: root.room
    }

    FormCard.FormHeader {
        title: i18n("Privileged Users")
    }
    FormCard.FormCard {
        Repeater {
            model: KSortFilterProxyModel {
                sourceModel: RoomManager.userListModel
                sortRoleName: "powerLevel"
                sortOrder: Qt.DescendingOrder
                filterRowCallback: function (source_row, source_parent) {
                    let powerLevelRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), UserListModel.PowerLevelRole);
                    return powerLevelRole != 0;
                }
            }
            delegate: FormCard.FormTextDelegate {
                id: privilegedUserDelegate
                required property string userId
                required property string name
                required property int powerLevel
                required property string powerLevelString

                text: name
                textItem.textFormat: Text.PlainText
                description: userId
                contentItem.children: RowLayout {
                    spacing: Kirigami.Units.largeSpacing
                    QQC2.Label {
                        id: powerLevelLabel
                        text: privilegedUserDelegate.powerLevelString
                        visible: !room.canSendState("m.room.power_levels") || (room.getUserPowerLevel(room.localMember.id) <= privilegedUserDelegate.powerLevel && privilegedUserDelegate.userId != room.localMember.id)
                        color: Kirigami.Theme.disabledTextColor
                    }
                    QQC2.ComboBox {
                        focusPolicy: Qt.NoFocus // provided by parent
                        model: PowerLevelModel {}
                        textRole: "name"
                        valueRole: "value"
                        visible: !powerLevelLabel.visible
                        Component.onCompleted: {
                            let index = indexOfValue(privilegedUserDelegate.powerLevel)
                            if (index === -1) {
                                displayText = privilegedUserDelegate.powerLevelString;
                            } else {
                                currentIndex = index;
                            }
                        }
                        onActivated: {
                            room.setUserPowerLevel(userId, currentValue);
                        }
                    }
                }
            }
        }
        FormCard.FormDelegateSeparator {
            below: userListSearchCard
        }
        FormCard.AbstractFormDelegate {
            id: userListSearchCard
            visible: room.canSendState("m.room.power_levels")

            contentItem: Kirigami.SearchField {
                id: userListSearchField

                autoAccept: false

                Layout.fillWidth: true

                Keys.onUpPressed: userListView.decrementCurrentIndex()
                Keys.onDownPressed: userListView.incrementCurrentIndex()

                onAccepted: {
                    let currentUser = userListView.itemAtIndex(userListView.currentIndex);
                    currentUser.action.trigger();
                }
            }
            QQC2.Popup {
                id: userListSearchPopup

                x: userListSearchField.x
                y: userListSearchField.y - height
                width: userListSearchField.width
                height: {
                    let maxHeight = userListSearchField.mapToGlobal(userListSearchField.x, userListSearchField.y).y - Kirigami.Units.largeSpacing * 3;
                    let minHeight = Kirigami.Units.gridUnit * 2 + userListSearchPopup.padding * 2;
                    let filterContentHeight = userListView.contentHeight + userListSearchPopup.padding * 2;
                    return Math.max(Math.min(filterContentHeight, maxHeight), minHeight);
                }
                padding: Kirigami.Units.smallSpacing
                leftPadding: Kirigami.Units.smallSpacing / 2
                rightPadding: Kirigami.Units.smallSpacing / 2
                modal: false
                onClosed: userListSearchField.text = ""

                background: Kirigami.ShadowedRectangle {
                    property color borderColor: Kirigami.Theme.textColor

                    Kirigami.Theme.colorSet: Kirigami.Theme.View
                    Kirigami.Theme.inherit: false

                    radius: Kirigami.Units.cornerRadius
                    color: Kirigami.Theme.backgroundColor

                    border {
                        color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
                        width: 1
                    }

                    shadow {
                        xOffset: 0
                        yOffset: 4
                        color: Qt.rgba(0, 0, 0, 0.3)
                        size: 8
                    }
                }

                contentItem: QQC2.ScrollView {
                    // HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
                    QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff

                    ListView {
                        id: userListView
                        clip: true

                        model: UserFilterModel {
                            id: userListFilterModel
                            sourceModel: RoomManager.userListModel
                            filterText: userListSearchField.text

                            onFilterTextChanged: {
                                if (filterText.length > 0 && !userListSearchPopup.visible) {
                                    userListSearchPopup.open();
                                } else if (filterText.length <= 0 && userListSearchPopup.visible) {
                                    userListSearchPopup.close();
                                }
                            }
                        }

                        delegate: Delegates.RoundedItemDelegate {
                            id: userListItem

                            required property string userId
                            required property string avatar
                            required property string name
                            required property int powerLevel
                            required property string powerLevelString

                            text: name

                            contentItem: RowLayout {
                                KirigamiComponents.Avatar {
                                    Layout.preferredWidth: Kirigami.Units.iconSizes.medium
                                    Layout.preferredHeight: Kirigami.Units.iconSizes.medium
                                    source: userListItem.avatar ? root.room.connection.makeMediaUrl(userListItem.avatar) : ""
                                    name: userListItem.name
                                }

                                Delegates.SubtitleContentItem {
                                    itemDelegate: userListItem
                                    subtitle: userListItem.userId
                                    labelItem.textFormat: Text.PlainText
                                    subtitleItem.textFormat: Text.PlainText
                                    Layout.fillWidth: true
                                }

                                QQC2.Label {
                                    visible: userListItem.powerLevel > 0

                                    text: userListItem.powerLevelString
                                    color: Kirigami.Theme.disabledTextColor
                                    textFormat: Text.PlainText
                                    wrapMode: Text.NoWrap
                                }
                            }

                            action: Kirigami.Action {
                                id: editPowerLevelAction
                                onTriggered: {
                                    userListSearchPopup.close();
                                    let dialog = powerLevelDialog.createObject(root.QQC2.Overlay.overlay, {
                                        room: root.room,
                                        userId: userListItem.userId,
                                        powerLevel: userListItem.powerLevel
                                    });
                                    dialog.open();
                                }
                            }

                            Component {
                                id: powerLevelDialog
                                PowerLevelDialog {
                                    id: powerLevelDialog
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    FormCard.FormHeader {
        visible: room.canSendState("m.room.power_levels")
        title: i18n("Default permissions")
    }
    FormCard.FormCard {
        visible: room.canSendState("m.room.power_levels")
        Repeater {
            model: KSortFilterProxyModel {
                sourceModel: root.permissionsModel
                filterRowCallback: function (source_row, source_parent) {
                    return sourceModel.data(sourceModel.index(source_row, 0, source_parent), PermissionsModel.IsDefaultValueRole);
                }
            }
            delegate: FormCard.FormComboBoxDelegate {
                required property string name
                required property string subtitle
                required property string type
                required property int level
                required property string levelName

                text: name
                description: subtitle
                textRole: "name"
                valueRole: "value"
                model: root.powerLevelModel
                Component.onCompleted: {
                    let index = indexOfValue(level)
                    if (index === -1) {
                        displayText = levelName;
                    } else {
                        currentIndex = index;
                    }
                }
                onCurrentValueChanged: if (root.room.canSendState("m.room.power_levels")) {
                    root.permissionsModel.setPowerLevel(type, currentValue);
                }
            }
        }
    }

    FormCard.FormHeader {
        visible: room.canSendState("m.room.power_levels")
        title: i18n("Basic permissions")
    }
    FormCard.FormCard {
        visible: room.canSendState("m.room.power_levels")
        Repeater {
            model: KSortFilterProxyModel {
                sourceModel: root.permissionsModel
                filterRowCallback: function (source_row, source_parent) {
                    return sourceModel.data(sourceModel.index(source_row, 0, source_parent), PermissionsModel.IsBasicPermissionRole);
                }
            }
            delegate: FormCard.FormComboBoxDelegate {
                required property string name
                required property string subtitle
                required property string type
                required property int level
                required property string levelName

                text: name
                description: subtitle
                textRole: "name"
                valueRole: "value"
                model: root.powerLevelModel
                Component.onCompleted: {
                    let index = indexOfValue(level)
                    if (index === -1) {
                        displayText = levelName;
                    } else {
                        currentIndex = index;
                    }
                }
                onCurrentValueChanged: if (root.room.canSendState("m.room.power_levels")) {
                    root.permissionsModel.setPowerLevel(type, currentValue);
                }
            }
        }
    }

    FormCard.FormHeader {
        visible: room.canSendState("m.room.power_levels")
        title: i18n("Event permissions")
    }
    FormCard.FormCard {
        visible: room.canSendState("m.room.power_levels")
        Repeater {
            model: KSortFilterProxyModel {
                sourceModel: root.permissionsModel
                filterRowCallback: function (source_row, source_parent) {
                    let isBasicPermissionRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), PermissionsModel.IsBasicPermissionRole);
                    let isDefaultValueRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), PermissionsModel.IsDefaultValueRole);
                    return !isBasicPermissionRole && !isDefaultValueRole;
                }
            }
            delegate: FormCard.FormComboBoxDelegate {
                required property string name
                required property string subtitle
                required property string type
                required property int level
                required property string levelName

                text: name
                description: subtitle
                textRole: "name"
                valueRole: "value"
                model: root.powerLevelModel
                Component.onCompleted: {
                    let index = indexOfValue(level)
                    if (index === -1) {
                        displayText = levelName;
                    } else {
                        currentIndex = index;
                    }
                }
                onCurrentValueChanged: if (room.canSendState("m.room.power_levels")) {
                    root.permissionsModel.setPowerLevel(type, currentValue);
                }
            }
        }
        FormCard.AbstractFormDelegate {
            Layout.fillWidth: true

            contentItem: RowLayout {
                Kirigami.ActionTextField {
                    id: newEventAddField

                    Layout.fillWidth: true

                    placeholderText: i18n("Event Type…")
                    enabled: NotificationsManager.keywordNotificationAction !== PushRuleAction.Unknown

                    rightActions: Kirigami.Action {
                        icon.name: "edit-clear"
                        visible: newEventAddField.text.length > 0
                        onTriggered: {
                            newEventAddField.text = "";
                        }
                    }

                    onAccepted: {
                        root.permissionsModel.setPowerLevel(newEventAddField.text, newEventPowerLevel.currentValue);
                        newEventAddField.text = "";
                    }
                }
                QQC2.ComboBox {
                    id: newEventPowerLevel
                    focusPolicy: Qt.NoFocus // provided by parent
                    model: root.powerLevelModel
                    textRole: "name"
                    valueRole: "value"
                }
                QQC2.Button {
                    id: addButton

                    text: i18n("Add keyword")
                    Accessible.name: text
                    icon.name: "list-add"
                    display: QQC2.AbstractButton.IconOnly
                    enabled: newEventAddField.text.length > 0

                    onClicked: {
                        root.permissionsModel.setPowerLevel(newEventAddField.text, newEventPowerLevel.currentValue);
                        newEventAddField.text = "";
                    }

                    QQC2.ToolTip {
                        text: addButton.text
                        delay: Kirigami.Units.toolTipDelay
                    }
                }
            }
        }
    }
}
