// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
// SPDX-License-Identifier: LGPL-3.0-or-later

import QtQuick 2.12
import QtQuick.Layouts 1.12
import "../../../.."
import "../../../../Base"
import "../../../../Base/Buttons"

HListView {
    id: root

    property string userId
    property string roomId
    property int ownPowerLevel
    property int canSetPowerLevels
    property QtObject member  // RoomMember model item
    property HStackView stackView
    property Item focusOnExit

    property bool powerLevelFieldFocused: false

    property string setPowerFutureId: ""
    property string getPresenceFutureId: ""

    function loadDevices() {
         py.callClientCoro(userId, "member_devices", [member.id], devices => {
            root.model.clear()

            for (const device of devices)
                root.model.append(device)
        })
    }

    function exit() {
        stackView.pop()
        focusOnExit.forceActiveFocus()
    }

    clip: true
    bottomMargin: theme.spacing
    model: ListModel {}
    delegate: MemberDeviceDelegate {
        width: root.width
        userId: root.userId
        deviceOwner: member.id
        deviceOwnerDisplayName: member.display_name
        stackView: root.stackView

        onTrustSet: trust => root.loadDevices()
    }

    section.property: "type"
    section.delegate: MemberDeviceSection {
        width: root.width
    }

    header: HColumnLayout {
        x: theme.spacing
        width: root.width - x * 2
        spacing: theme.spacing * 1.5

        Component.onCompleted:
            powerLevel.enabled ?
            powerLevel.item.forceActiveFocus() :
            root.currentIndex = 0

        HUserAvatar {
            clientUserId: chat.userId
            userId: member.id
            displayName: member.display_name
            mxc: member.avatar_url

            Layout.alignment: Qt.AlignHCenter
            Layout.fillWidth: true
            Layout.maximumWidth: 256 * theme.uiScale
            Layout.preferredHeight: width
            Layout.topMargin: theme.spacing

            HButton {
                x: -theme.spacing * 0.75
                y: x
                z: 999
                circle: true
                icon.name: "close-view"
                iconItem.small: true
                onClicked: root.exit()
            }
        }

        HColumnLayout {  // no spacing between these children
            HLabel {
                wrapMode: HLabel.Wrap
                horizontalAlignment: Qt.AlignHCenter
                color: utils.nameColor(member.display_name || member.id)
                text: member.display_name.trim() || member.id

                Layout.fillWidth: true
            }

            HLabel {
                wrapMode: HLabel.Wrap
                horizontalAlignment: Qt.AlignHCenter
                color: theme.colors.dimText
                text: member.id
                visible: member.display_name.trim() !== ""

                Layout.fillWidth: true
            }
        }

        HColumnLayout {
            HLabel {
                wrapMode: HLabel.Wrap
                horizontalAlignment: Qt.AlignHCenter

                text:
                    member.presence === "online" ? qsTr("Online") :
                    member.presence === "unavailable" ? qsTr("Unavailable") :
                    member.presence === "invisible" ? qsTr("Invisible") :
                    qsTr("Offline / Unknown")

                color:
                    member.presence === "online" ?
                    theme.colors.positiveText :

                    member.presence === "unavailable" ?
                    theme.colors.warningText :

                    theme.colors.halfDimText

                Layout.fillWidth: true
            }

            HLabel {
                wrapMode: HLabel.Wrap
                horizontalAlignment: Qt.AlignHCenter
                visible: ! member.currently_active && text !== ""
                color: theme.colors.dimText

                Timer {
                    repeat: true
                    triggeredOnStart: true

                    running:
                        ! member.currently_active &&
                        member.last_active_at > new Date(1)

                    interval:
                        new Date() - member.last_active_at < 60000 ?
                        1000 :
                        60000

                    onTriggered: parent.text = Qt.binding(() =>
                        qsTr("Last seen %1 ago").arg(utils.formatRelativeTime(
                            new Date() - member.last_active_at, false,
                        ))
                    )
                }

                Layout.fillWidth: true
            }
        }

        HLabel {
            wrapMode: HLabel.Wrap
            text: member.status_msg.trim()
            visible: text !== ""
            horizontalAlignment: lineCount > 1 ? Qt.AlignLeft : Qt.AlignHCenter
            color: theme.colors.halfDimText

            Layout.fillWidth: true
        }

        HLabeledItem {
            id: powerLevel
            elementsOpacity: item.field.opacity
            enabled:
                root.canSetPowerLevels &&
                (
                    root.ownPowerLevel > member.power_level ||
                    (root.ownPowerLevel === 100 && member.id === userId)
                )

            label.text: qsTr("Power level:")
            label.horizontalAlignment: Qt.AlignHCenter

            errorLabel.horizontalAlignment: Qt.AlignHCenter
            errorLabel.text:
                ! item.changed ?
                "" :

                item.fieldOverMaximum && root.userId === member.id ?
                qsTr("Can't set your own level higher") :

                item.fieldOverMaximum ?
                qsTr("Can't set level higher than your own") :

                item.uncappedLevel === root.ownPowerLevel ?
                qsTr("You won't be able to demote this user") :

                item.uncappedLevel <
                root.ownPowerLevel && root.userId === member.id ?
                qsTr("You won't be able to regain power") :

                ""

            errorLabel.color:
                item.uncappedLevel === root.ownPowerLevel ||
                (
                    item.uncappedLevel <
                    root.ownPowerLevel && root.userId === member.id
                ) ?
                theme.colors.warningText :
                theme.colors.errorText

            Layout.preferredWidth: parent.width

            PowerLevelControl {
                width: parent.width
                defaultLevel: member.power_level
                maximumLevel: root.ownPowerLevel
                rowSpacing: powerLevel.spacing

                onAccepted: applyButton.clicked()
                onFieldFocusedChanged:
                    root.powerLevelFieldFocused = fieldFocused
            }
        }

        HRowLayout {
            visible: scale > 0
            id: buttonsLayout
            scale: powerLevel.item.changed ? 1 : 0

            Layout.preferredWidth: parent.width
            Layout.preferredHeight: implicitHeight * scale
            Layout.topMargin: -theme.spacing

            HSpacer {}

            ApplyButton {
                id: applyButton
                enabled: ! powerLevel.item.fieldOverMaximum
                loading: setPowerFutureId !== ""
                text: ""
                onClicked: {
                    setPowerFutureId = py.callClientCoro(
                        userId,
                        "room_set_member_power",
                        [roomId, member.id, powerLevel.item.level],
                        () => { setPowerFutureId = "" }
                    )
                }

                Layout.fillWidth: false
                Layout.alignment: Qt.AlignCenter
            }

            CancelButton {
                text: ""
                onClicked: {
                    py.cancelCoro(setPowerFutureId)
                    setPowerFutureId = ""
                    powerLevel.item.reset()
                }

                Layout.fillWidth: false
                Layout.alignment: Qt.AlignCenter
            }

            HSpacer {}
        }

        Item {
            // This item is just to have some spacing at the bottom of header
            visible: root.count > 0
            Layout.fillWidth: true
        }
    }

    Component.onCompleted: {
        loadDevices()

        if (member.presence === "offline" &&
            member.last_active_at < new Date(1))
        {
            getPresenceFutureId = py.callClientCoro(
                userId,
                "get_offline_presence",
                [member.id],
                () => { getPresenceFutureId = "" }
            )
        }
    }

    Component.onDestruction: {
        if (setPowerFutureId) py.cancelCoro(setPowerFutureId)
        if (getPresenceFutureId) py.cancelCoro(getPresenceFutureId)
    }

    Keys.onEnterPressed: Keys.onReturnPressed(event)
    Keys.onReturnPressed: if (! root.powerLevelFieldFocused && currentItem) {
        currentItem.leftClicked()
        currentItem.clicked()
    }
    Keys.onEscapePressed: root.exit()

    Connections {
        target: py.eventHandlers
        onDeviceUpdateSignal: forAccount => {
            if (forAccount === root.userId) root.loadDevices()
        }
    }
}
