// SPDX-FileCopyrightText: 2020-2024 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Effects

import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.workspace.keyboardlayout 1.0
import org.kde.plasma.private.mobileshell as MobileShell

import org.kde.kirigami as Kirigami

Item {
    id: root
    required property real openProgress
    required property var lockScreenState
    readonly property int layoutAnimationDuration: openProgress > 0.5 ? MobileShell.Motion.duration(MobileShell.Motion.Emphasized) : 0
    readonly property int shortAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.EffectsFast)

    property alias passwordBar: passwordBar

    MobileShell.HapticsEffect {
        id: haptics
    }

    // Column layout - most cases
    ColumnLayout {
        id: keypadVerticalContainer
        visible: root.height > Kirigami.Units.gridUnit * 25

        anchors.centerIn: parent
        spacing: Kirigami.Units.gridUnit * 2

        LayoutItemProxy {
            id: verticalHeaderProxy
            target: header
        }
        LayoutItemProxy { target: keypadGrid }

        states: [
            State {
                name: "keypad"
                when: !lockScreenState.isKeyboardMode
                AnchorChanges {
                    target: verticalHeaderProxy; anchors.top: keypadVerticalContainer.top
                }
                PropertyChanges {
                    target: verticalHeaderProxy; anchors.verticalCenterOffset: 0
                }
            },
            State {
                name: "keyboard"
                when: lockScreenState.isKeyboardMode
                AnchorChanges {
                    target: verticalHeaderProxy; anchors.verticalCenter: keypadVerticalContainer.verticalCenter
                }
                PropertyChanges {
                    target: verticalHeaderProxy; anchors.verticalCenterOffset: -Kirigami.Units.gridUnit * 3
                }
            }
        ]

        transitions: Transition {
            AnchorAnimation {
                easing.type: MobileShell.Motion.easing(MobileShell.Motion.Emphasized)
                duration: root.layoutAnimationDuration
            }
        }
    }

    // Row layout - used when there is restricted height
    RowLayout {
        id: keypadHorizontalContainer
        visible: !keypadVerticalContainer.visible

        anchors.centerIn: parent
        spacing: Kirigami.Units.gridUnit * 2

        LayoutItemProxy {
            id: horizontalHeaderProxy
            target: header
        }
        LayoutItemProxy { target: keypadGrid }

        states: [
            State {
                name: "keypad"
                when: !lockScreenState.isKeyboardMode
                AnchorChanges {
                    target: horizontalHeaderProxy; anchors.left: keypadHorizontalContainer.left
                }
            },
            State {
                name: "keyboard"
                when: lockScreenState.isKeyboardMode
                AnchorChanges {
                    target: horizontalHeaderProxy; anchors.horizontalCenter: keypadHorizontalContainer.horizontalCenter
                }
            }
        ]

        transitions: Transition {
            AnchorAnimation {
                easing.type: MobileShell.Motion.easing(MobileShell.Motion.Emphasized)
                duration: root.layoutAnimationDuration
            }
        }
    }

    ColumnLayout {
        id: header
        spacing: Kirigami.Units.gridUnit

        // label ("wrong pin", "enter pin")
        Label {
            id: descriptionLabel
            Layout.alignment: Qt.AlignHCenter
            opacity: root.lockScreenState.password.length === 0 ? 1 : 0
            text: root.lockScreenState.pinLabel
            font.pointSize: 12
            font.bold: true
            color: 'white'

            // Enforce extra margin at top of vertical container
            Layout.topMargin: keypadVerticalContainer.visible ? Kirigami.Units.gridUnit * 3 : 0

            Behavior on opacity {
                MobileShell.MotionNumberAnimation { type: MobileShell.Motion.EffectsFast; duration: root.shortAnimationDuration }
            }
        }

        // pin display and bar
        PasswordBar {
            id: passwordBar
            Layout.preferredWidth: Kirigami.Units.gridUnit * 14
            Layout.preferredHeight: Kirigami.Units.gridUnit * 2.5

            lockScreenState: root.lockScreenState
            isKeypadOpen: root.openProgress >= 0.9
            enabled: root.openProgress >= 0.8
        }
    }

    GridLayout {
        id: keypadGrid
        columnSpacing: Kirigami.Units.gridUnit
        rowSpacing: Kirigami.Units.gridUnit
        uniformCellHeights: true
        uniformCellWidths: true

        readonly property real intendedWidth: Kirigami.Units.gridUnit * 14

        Layout.preferredWidth: Kirigami.Units.gridUnit * 14
        Layout.preferredHeight: Kirigami.Units.gridUnit * 22

        readonly property real cellLength: (intendedWidth - columnSpacing * 2) / 3

        columns: 3

        // numpad keys
        Repeater {
            model: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "R", "0", "E"]

            delegate: AbstractButton {
                id: button
                implicitWidth: keypadGrid.cellLength
                implicitHeight: keypadGrid.cellLength
                visible: modelData.length > 0
                enabled: root.openProgress >= 0.8 && !lockScreenState.isKeyboardMode // Only enable after a certain point in animation

                opacity: enabled
                Behavior on opacity {
                    SequentialAnimation {
                        PauseAnimation { duration: MobileShell.Motion.enabled ? 20 * index : 0 }
                        MobileShell.MotionNumberAnimation { type: MobileShell.Motion.Emphasized; duration: root.layoutAnimationDuration }
                    }
                }

                background: Rectangle {
                    readonly property real restingOpacity: (modelData !== "R" && modelData !== "E") ? 0.2 : 0.0
                    radius: width
                    color: Qt.rgba(255, 255, 255,
                                    button.pressed ? 0.5 : restingOpacity)
                }

                onPressedChanged: {
                    if (pressed) {
                        haptics.buttonVibrate();
                    }
                }

                onClicked: {
                    if (modelData === "R") {
                        passwordBar.backspace();
                    } else if (modelData === "E") {
                        passwordBar.enter();
                    } else {
                        passwordBar.keyPress(modelData);
                    }
                }

                onPressAndHold: {
                    if (modelData === "R") {
                        haptics.buttonVibrate();
                        passwordBar.clear();
                    }
                }

                contentItem: Item {
                    PlasmaComponents.Label {
                        visible: modelData !== "R" && modelData !== "E"
                        text: modelData
                        anchors.centerIn: parent
                        font.pointSize: 18
                        color: 'white'
                    }

                    Kirigami.Icon {
                        visible: modelData === "R" || modelData === "E"
                        anchors.centerIn: parent
                        width: Kirigami.Units.iconSizes.small
                        height: Kirigami.Units.iconSizes.small
                        source: modelData === "R" ? "edit-clear" : "go-next"
                        Kirigami.Theme.inherit: false
                        Kirigami.Theme.colorSet: Kirigami.Theme.Complementary
                    }
                }
            }
        }
    }
}
