pragma ComponentBehavior: Bound

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Caelestia.Config
import qs.components
import qs.services

ColumnLayout {
    id: root

    function refresh() {
        kb.refresh();
    }

    spacing: Tokens.spacing.small
    width: Tokens.sizes.bar.kbLayoutWidth

    Component.onCompleted: kb.start()

    KbLayoutModel {
        id: kb
    }

    StyledText {
        Layout.topMargin: Tokens.padding.medium
        Layout.rightMargin: Tokens.padding.extraSmall
        text: qsTr("Keyboard Layouts")
        font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
    }

    ListView {
        id: list

        model: kb.visibleModel

        Layout.fillWidth: true
        Layout.rightMargin: Tokens.padding.extraSmall
        Layout.topMargin: Tokens.spacing.small

        clip: true
        interactive: true
        implicitHeight: Math.min(contentHeight, 320)
        visible: kb.visibleModel.count > 0
        spacing: Tokens.spacing.small

        add: Transition {
            NumberAnimation {
                properties: "opacity"
                from: 0
                to: 1
                duration: 140
            }
            NumberAnimation {
                properties: "y"
                duration: 180
                easing.type: Easing.OutCubic
            }
        }
        remove: Transition {
            NumberAnimation {
                properties: "opacity"
                to: 0
                duration: 100
            }
        }
        move: Transition {
            NumberAnimation {
                properties: "y"
                duration: 180
                easing.type: Easing.OutCubic
            }
        }
        displaced: Transition {
            NumberAnimation {
                properties: "y"
                duration: 180
                easing.type: Easing.OutCubic
            }
        }

        delegate: Item {
            id: kbDelegate

            required property int layoutIndex
            required property string label
            readonly property bool isDisabled: layoutIndex > 3

            width: list.width
            height: Math.max(36, rowText.implicitHeight + Tokens.padding.small)
            ToolTip.visible: isDisabled && layer.containsMouse
            ToolTip.text: "XKB limitation: maximum 4 layouts allowed"

            StateLayer {
                id: layer

                onClicked: {
                    if (!kbDelegate.isDisabled)
                        kb.switchTo(kbDelegate.layoutIndex);
                }

                anchors.left: parent.left
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                implicitHeight: parent.height - 4
                radius: Tokens.rounding.full
                enabled: !kbDelegate.isDisabled
            }

            StyledText {
                id: rowText

                anchors.verticalCenter: layer.verticalCenter
                anchors.left: layer.left
                anchors.right: layer.right
                anchors.leftMargin: Tokens.padding.extraSmall
                anchors.rightMargin: Tokens.padding.extraSmall
                text: kbDelegate.label
                elide: Text.ElideRight
                opacity: kbDelegate.isDisabled ? 0.4 : 1.0
            }
        }
    }

    Rectangle {
        visible: kb.activeLabel.length > 0
        Layout.fillWidth: true
        Layout.rightMargin: Tokens.padding.extraSmall
        Layout.topMargin: Tokens.spacing.small

        implicitHeight: 1
        color: Colours.palette.m3onSurfaceVariant
        opacity: 0.35
    }

    RowLayout {
        id: activeRow

        visible: kb.activeLabel.length > 0
        Layout.fillWidth: true
        Layout.rightMargin: Tokens.padding.extraSmall
        Layout.topMargin: Tokens.spacing.small
        spacing: Tokens.spacing.small

        opacity: 1
        scale: 1

        MaterialIcon {
            text: "keyboard"
            color: Colours.palette.m3primary
        }

        StyledText {
            Layout.fillWidth: true
            text: kb.activeLabel
            elide: Text.ElideRight
            font: Tokens.font.body.builders.medium.weight(Font.Medium).build()
            color: Colours.palette.m3primary
        }

        Connections {
            function onActiveLabelChanged() {
                if (!activeRow.visible)
                    return;
                popIn.restart();
            }

            target: kb
        }

        SequentialAnimation {
            id: popIn

            running: false

            ParallelAnimation {
                NumberAnimation {
                    target: activeRow
                    property: "opacity"
                    to: 0.0
                    duration: 70
                }
                NumberAnimation {
                    target: activeRow
                    property: "scale"
                    to: 0.92
                    duration: 70
                }
            }

            ParallelAnimation {
                NumberAnimation {
                    target: activeRow
                    property: "opacity"
                    to: 1.0
                    duration: 160
                    easing.type: Easing.OutCubic
                }
                NumberAnimation {
                    target: activeRow
                    property: "scale"
                    to: 1.0
                    duration: 220
                    easing.type: Easing.OutBack
                }
            }
        }
    }
}
