import Quickshell
import Quickshell.Io
import Quickshell.Services.Pipewire
import Quickshell.Wayland
import QtQuick
import QtQuick.Layouts
import "../shared" as Shared

Scope {
    id: root

    PwObjectTracker { objects: [Pipewire.defaultAudioSink, Pipewire.defaultAudioSource] }

    property string osdIcon: ""
    property real osdValue: 0
    property bool osdMuted: false
    property string osdLabel: ""
    property bool osdVisible: false

    function showOsd(icon, value, muted, label) {
        osdIcon = icon;
        osdValue = value;
        osdMuted = muted;
        osdLabel = label;
        osdVisible = true;
        hideTimer.restart();
    }

    Timer {
        id: hideTimer
        interval: 1500
        onTriggered: root.osdVisible = false
    }

    // Brightness is event-driven: the Hyprland brightness keybinds set the level
    // and then push the new percentage here via `qs ipc call osd brightness <0-100>`.
    // (Volume/mic remain event-driven via the PipeWire Connections below.)
    IpcHandler {
        target: "osd"
        function brightness(pct: string): void {
            let frac = Math.max(0, Math.min(1, (parseFloat(pct) || 0) / 100));
            root.showOsd("\u{f00df}", frac, false, "Brightness");
        }
    }

    // Event-driven audio change detection
    property var sinkAudio: Pipewire.defaultAudioSink?.audio ?? null
    property var sourceAudio: Pipewire.defaultAudioSource?.audio ?? null

    Connections {
        target: root.sinkAudio
        function onVolumeChanged() {
            let a = root.sinkAudio;
            if (a) root.showOsd("\u{f057e}", a.volume, a.muted, "Volume");
        }
        function onMutedChanged() {
            let a = root.sinkAudio;
            if (a) root.showOsd(a.muted ? "\u{f057f}" : "\u{f057e}", a.volume, a.muted, a.muted ? "Muted" : "Volume");
        }
    }

    Connections {
        target: root.sourceAudio
        function onVolumeChanged() {
            let a = root.sourceAudio;
            if (a) root.showOsd("\u{f036c}", a.volume, a.muted, "Mic");
        }
        function onMutedChanged() {
            let a = root.sourceAudio;
            if (a) root.showOsd(a.muted ? "\u{f036d}" : "\u{f036c}", a.volume, a.muted, a.muted ? "Mic muted" : "Mic");
        }
    }

    Variants {
        model: Quickshell.screens

        delegate: Component {
            PanelWindow {
                required property var modelData
                screen: modelData
                WlrLayershell.namespace: "quickshell:osd"
                surfaceFormat { opaque: false }

                visible: modelData.name === Shared.Config.monitor && root.osdVisible

                anchors {
                    top: true
                    right: true
                    bottom: true
                }

                exclusionMode: ExclusionMode.Ignore
                implicitWidth: Shared.Theme.barWidth + Shared.Theme.popoutWidth + 12
                color: "transparent"

                Rectangle {
                    anchors.right: parent.right
                    anchors.rightMargin: Shared.Theme.barWidth + 12
                    anchors.verticalCenter: parent.verticalCenter
                    width: 44
                    height: 180
                    radius: 22
                    color: Shared.Theme.popoutBackground
                    border.width: 1
                    border.color: Shared.Theme.borderSubtle

                    opacity: root.osdVisible ? 1.0 : 0.0
                    scale: root.osdVisible ? 1.0 : 0.95
                    transformOrigin: Item.Right

                    Behavior on opacity { NumberAnimation { duration: 120; easing.type: Easing.OutCubic } }
                    Behavior on scale { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }

                    ColumnLayout {
                        anchors.fill: parent
                        anchors.topMargin: 12
                        anchors.bottomMargin: 12
                        spacing: 8

                        // Percentage
                        Text {
                            Layout.alignment: Qt.AlignHCenter
                            text: root.osdMuted ? "M" : Math.round(root.osdValue * 100)
                            color: root.osdMuted ? Shared.Theme.overlay0 : Shared.Theme.text
                            font.pixelSize: Shared.Theme.fontSmall
                            font.family: Shared.Theme.fontFamily
                            font.bold: true
                        }

                        // Vertical bar (fills bottom-up)
                        Rectangle {
                            Layout.fillHeight: true
                            Layout.alignment: Qt.AlignHCenter
                            implicitWidth: 6
                            radius: 3
                            color: Shared.Theme.surface0

                            Rectangle {
                                anchors.left: parent.left
                                anchors.right: parent.right
                                anchors.bottom: parent.bottom
                                height: root.osdMuted ? 0 : parent.height * Math.min(1, root.osdValue)
                                radius: 3
                                color: root.osdMuted ? Shared.Theme.overlay0 : Shared.Theme.sky
                                Behavior on height { NumberAnimation { duration: 80; easing.type: Easing.OutCubic } }
                            }
                        }

                        // Icon
                        Text {
                            Layout.alignment: Qt.AlignHCenter
                            text: root.osdIcon
                            color: root.osdMuted ? Shared.Theme.overlay0 : Shared.Theme.sky
                            font.pixelSize: 16
                            font.family: Shared.Theme.iconFont
                        }
                    }
                }
            }
        }
    }
}
