pragma ComponentBehavior: Bound

import ".."
import "../components"
import QtQuick
import QtQuick.Layouts
import Quickshell.Bluetooth
import Caelestia.Config
import qs.components
import qs.components.controls
import qs.components.effects
import qs.services

ColumnLayout {
    id: root

    required property Session session

    spacing: Tokens.spacing.medium

    SettingsHeader {
        icon: "bluetooth"
        title: qsTr("Bluetooth Settings")
    }

    StyledText {
        Layout.topMargin: Tokens.spacing.largeIncreased
        text: qsTr("Adapter status")
        font: Tokens.font.body.builders.large.weight(Font.Medium).build()
    }

    StyledText {
        text: qsTr("General adapter settings")
        color: Colours.palette.m3outline
    }

    StyledRect {
        Layout.fillWidth: true
        implicitHeight: adapterStatus.implicitHeight + Tokens.padding.extraLargeIncreased

        radius: Tokens.rounding.large
        color: Colours.tPalette.m3surfaceContainer

        ColumnLayout {
            id: adapterStatus

            anchors.left: parent.left
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
            anchors.margins: Tokens.padding.large

            spacing: Tokens.spacing.large

            Toggle {
                label: qsTr("Powered")
                checked: Bluetooth.defaultAdapter?.enabled ?? false
                toggle.onToggled: {
                    const adapter = Bluetooth.defaultAdapter;
                    if (adapter)
                        adapter.enabled = checked;
                }
            }

            Toggle {
                label: qsTr("Discoverable")
                checked: Bluetooth.defaultAdapter?.discoverable ?? false
                toggle.onToggled: {
                    const adapter = Bluetooth.defaultAdapter;
                    if (adapter)
                        adapter.discoverable = checked;
                }
            }

            Toggle {
                label: qsTr("Pairable")
                checked: Bluetooth.defaultAdapter?.pairable ?? false
                toggle.onToggled: {
                    const adapter = Bluetooth.defaultAdapter;
                    if (adapter)
                        adapter.pairable = checked;
                }
            }
        }
    }

    StyledText {
        Layout.topMargin: Tokens.spacing.largeIncreased
        text: qsTr("Adapter properties")
        font: Tokens.font.body.builders.large.weight(Font.Medium).build()
    }

    StyledText {
        text: qsTr("Per-adapter settings")
        color: Colours.palette.m3outline
    }

    StyledRect {
        Layout.fillWidth: true
        implicitHeight: adapterSettings.implicitHeight + Tokens.padding.extraLargeIncreased

        radius: Tokens.rounding.large
        color: Colours.tPalette.m3surfaceContainer

        ColumnLayout {
            id: adapterSettings

            anchors.left: parent.left
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
            anchors.margins: Tokens.padding.large

            spacing: Tokens.spacing.large

            RowLayout {
                Layout.fillWidth: true
                spacing: Tokens.spacing.medium

                StyledText {
                    Layout.fillWidth: true
                    text: qsTr("Current adapter")
                }

                Item {
                    id: adapterPickerButton

                    property bool expanded

                    implicitWidth: adapterPicker.implicitWidth + Tokens.padding.medium * 2
                    implicitHeight: adapterPicker.implicitHeight + Tokens.padding.large

                    StateLayer {
                        onClicked: {
                            adapterPickerButton.expanded = !adapterPickerButton.expanded;
                        }

                        radius: Tokens.rounding.medium
                    }

                    RowLayout {
                        id: adapterPicker

                        anchors.fill: parent
                        anchors.margins: Tokens.padding.medium
                        anchors.topMargin: Tokens.padding.small
                        anchors.bottomMargin: Tokens.padding.small
                        spacing: Tokens.spacing.medium

                        StyledText {
                            Layout.leftMargin: Tokens.padding.extraSmall
                            text: Bluetooth.defaultAdapter?.name ?? qsTr("None")
                        }

                        MaterialIcon {
                            text: "expand_more"
                        }
                    }

                    Elevation {
                        anchors.fill: adapterListBg
                        radius: adapterListBg.radius
                        opacity: adapterPickerButton.expanded ? 1 : 0
                        scale: adapterPickerButton.expanded ? 1 : 0.7
                        level: 2

                        Behavior on opacity {
                            Anim {}
                        }

                        Behavior on scale {
                            Anim {
                                type: Anim.FastSpatial
                            }
                        }
                    }

                    StyledClippingRect {
                        id: adapterListBg

                        anchors.left: parent.left
                        anchors.right: parent.right
                        anchors.bottom: parent.bottom
                        implicitHeight: adapterPickerButton.expanded ? adapterList.implicitHeight : adapterPickerButton.implicitHeight

                        color: Colours.palette.m3secondaryContainer
                        radius: Tokens.rounding.medium
                        opacity: adapterPickerButton.expanded ? 1 : 0
                        scale: adapterPickerButton.expanded ? 1 : 0.7

                        ColumnLayout {
                            id: adapterList

                            anchors.left: parent.left
                            anchors.right: parent.right
                            anchors.verticalCenter: parent.verticalCenter

                            spacing: 0

                            Repeater {
                                model: Bluetooth.adapters

                                Item {
                                    id: adapter

                                    required property BluetoothAdapter modelData

                                    Layout.fillWidth: true
                                    implicitHeight: adapterInner.implicitHeight + Tokens.padding.medium * 2

                                    StateLayer {
                                        onClicked: {
                                            adapterPickerButton.expanded = false;
                                            root.session.bt.currentAdapter = adapter.modelData;
                                        }

                                        disabled: !adapterPickerButton.expanded
                                    }

                                    RowLayout {
                                        id: adapterInner

                                        anchors.left: parent.left
                                        anchors.right: parent.right
                                        anchors.verticalCenter: parent.verticalCenter
                                        anchors.margins: Tokens.padding.medium
                                        spacing: Tokens.spacing.medium

                                        StyledText {
                                            Layout.fillWidth: true
                                            Layout.leftMargin: Tokens.padding.extraSmall
                                            text: adapter.modelData.name
                                            color: Colours.palette.m3onSecondaryContainer
                                        }

                                        MaterialIcon {
                                            text: "check"
                                            color: Colours.palette.m3onSecondaryContainer
                                            visible: adapter.modelData === root.session.bt.currentAdapter
                                        }
                                    }
                                }
                            }
                        }

                        Behavior on opacity {
                            Anim {}
                        }

                        Behavior on scale {
                            Anim {
                                type: Anim.FastSpatial
                            }
                        }

                        Behavior on implicitHeight {
                            Anim {}
                        }
                    }
                }
            }

            RowLayout {
                Layout.fillWidth: true
                spacing: Tokens.spacing.medium

                StyledText {
                    Layout.fillWidth: true
                    text: qsTr("Discoverable timeout")
                }

                CustomSpinBox {
                    min: 0
                    value: root.session.bt.currentAdapter?.discoverableTimeout ?? 0
                    onValueModified: value => {
                        if (root.session.bt.currentAdapter) {
                            root.session.bt.currentAdapter.discoverableTimeout = value;
                        }
                    }
                }
            }

            RowLayout {
                Layout.fillWidth: true
                spacing: Tokens.spacing.small

                Item {
                    id: renameAdapter

                    Layout.fillWidth: true
                    Layout.rightMargin: Tokens.spacing.small

                    implicitHeight: renameLabel.implicitHeight + adapterNameEdit.implicitHeight

                    states: State {
                        name: "editingAdapterName"
                        when: root.session.bt.editingAdapterName

                        AnchorChanges {
                            target: adapterNameEdit
                            anchors.top: renameAdapter.top
                        }
                        PropertyChanges {
                            renameAdapter.implicitHeight: adapterNameEdit.implicitHeight
                            renameLabel.opacity: 0
                            adapterNameEdit.padding: Tokens.padding.medium
                        }
                    }

                    transitions: Transition {
                        AnchorAnim {
                            type: AnchorAnim.Standard
                        }
                        Anim {
                            properties: "implicitHeight,opacity,padding"
                        }
                    }

                    StyledText {
                        id: renameLabel

                        anchors.left: parent.left

                        text: qsTr("Rename adapter (currently does not work)")
                        color: Colours.palette.m3outline
                        font: Tokens.font.label.small
                    }

                    StyledTextField {
                        id: adapterNameEdit

                        anchors.left: parent.left
                        anchors.right: parent.right
                        anchors.top: renameLabel.bottom
                        anchors.leftMargin: root.session.bt.editingAdapterName ? 0 : -Tokens.padding.medium

                        text: root.session.bt.currentAdapter?.name ?? ""
                        readOnly: !root.session.bt.editingAdapterName
                        onAccepted: {
                            root.session.bt.editingAdapterName = false;
                        }

                        leftPadding: Tokens.padding.medium
                        rightPadding: Tokens.padding.medium

                        background: StyledRect {
                            radius: Tokens.rounding.medium
                            border.width: 2
                            border.color: Colours.palette.m3primary
                            opacity: root.session.bt.editingAdapterName ? 1 : 0

                            Behavior on border.color {
                                CAnim {}
                            }

                            Behavior on opacity {
                                Anim {}
                            }
                        }

                        Behavior on anchors.leftMargin {
                            Anim {}
                        }
                    }
                }

                StyledRect {
                    implicitWidth: implicitHeight
                    implicitHeight: cancelEditIcon.implicitHeight + Tokens.padding.large

                    radius: Tokens.rounding.medium
                    color: Colours.palette.m3secondaryContainer
                    opacity: root.session.bt.editingAdapterName ? 1 : 0
                    scale: root.session.bt.editingAdapterName ? 1 : 0.5

                    StateLayer {
                        onClicked: {
                            root.session.bt.editingAdapterName = false;
                            adapterNameEdit.text = Qt.binding(() => root.session.bt.currentAdapter?.name ?? "");
                        }

                        color: Colours.palette.m3onSecondaryContainer
                        disabled: !root.session.bt.editingAdapterName
                    }

                    MaterialIcon {
                        id: cancelEditIcon

                        anchors.centerIn: parent
                        animate: true
                        text: "cancel"
                        color: Colours.palette.m3onSecondaryContainer
                    }

                    Behavior on opacity {
                        Anim {}
                    }

                    Behavior on scale {
                        Anim {
                            type: Anim.FastSpatial
                        }
                    }
                }

                StyledRect {
                    implicitWidth: implicitHeight
                    implicitHeight: editIcon.implicitHeight + Tokens.padding.large

                    radius: root.session.bt.editingAdapterName ? Tokens.rounding.medium : implicitHeight / 2 * Math.min(1, Tokens.rounding.scale)
                    color: Qt.alpha(Colours.palette.m3primary, root.session.bt.editingAdapterName ? 1 : 0)

                    StateLayer {
                        onClicked: {
                            root.session.bt.editingAdapterName = !root.session.bt.editingAdapterName;
                            if (root.session.bt.editingAdapterName)
                                adapterNameEdit.forceActiveFocus();
                            else
                                adapterNameEdit.accepted();
                        }

                        color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
                    }

                    MaterialIcon {
                        id: editIcon

                        anchors.centerIn: parent
                        animate: true
                        text: root.session.bt.editingAdapterName ? "check_circle" : "edit"
                        color: root.session.bt.editingAdapterName ? Colours.palette.m3onPrimary : Colours.palette.m3onSurface
                    }

                    Behavior on radius {
                        Anim {}
                    }
                }
            }
        }
    }

    StyledText {
        Layout.topMargin: Tokens.spacing.largeIncreased
        text: qsTr("Adapter information")
        font: Tokens.font.body.builders.large.weight(Font.Medium).build()
    }

    StyledText {
        text: qsTr("Information about the default adapter")
        color: Colours.palette.m3outline
    }

    StyledRect {
        Layout.fillWidth: true
        implicitHeight: adapterInfo.implicitHeight + Tokens.padding.extraLargeIncreased

        radius: Tokens.rounding.large
        color: Colours.tPalette.m3surfaceContainer

        ColumnLayout {
            id: adapterInfo

            anchors.left: parent.left
            anchors.right: parent.right
            anchors.verticalCenter: parent.verticalCenter
            anchors.margins: Tokens.padding.large

            spacing: Tokens.spacing.extraSmall

            StyledText {
                text: qsTr("Adapter state")
            }

            StyledText {
                text: Bluetooth.defaultAdapter ? BluetoothAdapterState.toString(Bluetooth.defaultAdapter.state) : qsTr("Unknown")
                color: Colours.palette.m3outline
                font: Tokens.font.body.small
            }

            StyledText {
                Layout.topMargin: Tokens.spacing.medium
                text: qsTr("Dbus path")
            }

            StyledText {
                text: Bluetooth.defaultAdapter?.dbusPath ?? ""
                color: Colours.palette.m3outline
                font: Tokens.font.body.small
            }

            StyledText {
                Layout.topMargin: Tokens.spacing.medium
                text: qsTr("Adapter id")
            }

            StyledText {
                text: Bluetooth.defaultAdapter?.adapterId ?? ""
                color: Colours.palette.m3outline
                font: Tokens.font.body.small
            }
        }
    }

    component Toggle: RowLayout {
        required property string label
        property alias checked: toggle.checked
        property alias toggle: toggle

        Layout.fillWidth: true
        spacing: Tokens.spacing.medium

        StyledText {
            Layout.fillWidth: true
            text: parent.label
        }

        StyledSwitch {
            id: toggle

            cLayer: 2
        }
    }
}
