import Quickshell
import Quickshell.Bluetooth
import Quickshell.Wayland
import Quickshell.Hyprland
import QtQuick
import QtMultimedia

PanelWindow {
    id: overlay
    anchors {
        top: true
        left: true
        right: true
        bottom: true
    }

    WlrLayershell.layer: WlrLayer.Overlay
    WlrLayershell.focusable: true
    WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
    WlrLayershell.namespace: "deltarune-startup-overlay"

    color: "#000000"
    exclusionMode: ExclusionMode.Ignore
    aboveWindows: true
    focusable: true

    property var bluetoothTargetNames: ["JBL Tune 525BT", "JBL GO"]
    property int bluetoothConnectAttemptMs: 3000
    property bool waitingForBluetooth: true
    property bool animationLaunchScheduled: false
    property bool animationStarted: false
    property bool bluetoothConnectRequested: false
    property int bluetoothTargetAttemptIndex: 0
    property string bluetoothActiveTargetName: ""

    function bluetoothModelCount() {
        if (bluetoothDeviceRepeater)
            return bluetoothDeviceRepeater.count;
        return 0;
    }

    function bluetoothDeviceAt(index) {
        const item = bluetoothDeviceRepeater.itemAt(index);
        if (!item)
            return null;
        return item.device || null;
    }

    function bluetoothDeviceName(device) {
        if (!device)
            return "";
        if (device.name && device.name.length > 0)
            return String(device.name);
        if (device.deviceName && device.deviceName.length > 0)
            return String(device.deviceName);
        return "";
    }

    function findBluetoothDeviceByName(targetName) {
        for (var i = 0; i < bluetoothModelCount(); i++) {
            var device = bluetoothDeviceAt(i);
            var deviceName = bluetoothDeviceName(device);
            console.log("Startup BT: candidate", i, deviceName, device ? Boolean(device.connected) : false);
            if (deviceName === targetName)
                return device;
        }
        console.log("Startup BT: target not found", targetName, "count", bluetoothModelCount());
        return null;
    }

    function findConnectedPreferredBluetoothDevice() {
        for (var i = 0; i < bluetoothTargetNames.length; i++) {
            var device = findBluetoothDeviceByName(bluetoothTargetNames[i]);
            if (device && device.connected)
                return device;
        }
        return null;
    }

    function resetBluetoothAttemptState() {
        bluetoothConnectRequested = false;
        bluetoothTargetAttemptIndex = 0;
        bluetoothActiveTargetName = "";
        bluetoothConnectAttemptTimer.stop();
    }

    function maybeStartBluetoothOrSkip() {
        console.log("Startup BT: maybeStartBluetoothOrSkip", "waiting", waitingForBluetooth, "requested", bluetoothConnectRequested, "active", bluetoothActiveTargetName, "attemptIndex", bluetoothTargetAttemptIndex);
        if (!waitingForBluetooth)
            return;

        const connectedDevice = findConnectedPreferredBluetoothDevice();
        if (connectedDevice) {
            console.log("Startup BT: preferred device connected, starting animation", bluetoothDeviceName(connectedDevice));
            beginAnimation();
            return;
        }

        if (bluetoothConnectRequested) {
            console.log("Startup BT: connect already requested, waiting on", bluetoothActiveTargetName);
            return;
        }

        for (var i = bluetoothTargetAttemptIndex; i < bluetoothTargetNames.length; i++) {
            var targetName = bluetoothTargetNames[i];
            var targetDevice = findBluetoothDeviceByName(targetName);
            if (!targetDevice)
                continue;

            bluetoothConnectRequested = true;
            bluetoothTargetAttemptIndex = i;
            bluetoothActiveTargetName = targetName;
            bluetoothConnectAttemptTimer.restart();
            console.log("Startup BT: requesting connect", targetName);
            targetDevice.connect();
            return;
        }

        console.log("Startup BT: no preferred devices available yet");
    }

    function beginAnimation() {
        console.log("Startup: beginAnimation", "started", animationStarted, "scheduled", animationLaunchScheduled);
        if (animationStarted || animationLaunchScheduled)
            return;
        waitingForBluetooth = false;
        bluetoothRetryTimer.stop();
        bluetoothConnectAttemptTimer.stop();
        animationLaunchScheduled = true;
        startupDelayTimer.restart();
    }

    function handlePrimaryAction() {
        console.log("Startup: handlePrimaryAction", "animationStarted", animationStarted, "waitingForBluetooth", waitingForBluetooth);
        if (!animationStarted)
            beginAnimation();
        else
            finishStartup();
    }

    function finishStartup() {
        console.log("Startup: finishStartup", "playbackState", player.playbackState);
        if (player.playbackState !== MediaPlayer.StoppedState)
            player.stop();
        else
            Qt.quit();
    }

    HyprlandFocusGrab {
        active: true
        windows: [overlay]
    }

    Component.onCompleted: {
        console.log("Startup: overlay completed", "btCount", bluetoothModelCount(), "targets", JSON.stringify(bluetoothTargetNames));
        maybeStartBluetoothOrSkip();
    }

    FocusScope {
        id: overlayFocus
        anchors.fill: parent
        focus: true

        Component.onCompleted: overlayFocus.forceActiveFocus()
        onVisibleChanged: if (visible)
            overlayFocus.forceActiveFocus()
        onFocusChanged: if (focus)
            overlayFocus.forceActiveFocus()

        Keys.onReleased: function (event) {
            switch (event.key) {
            case Qt.Key_Z:
            case Qt.Key_Return:
            case Qt.Key_Enter:
                event.accepted = true;
                overlay.handlePrimaryAction();
                return;
            }
        }
    }

    Connections {
        target: Bluetooth.devices
        ignoreUnknownSignals: true

        function onCountChanged() {
            if (overlay.waitingForBluetooth) {
                console.log("Startup BT: devices count changed", overlay.bluetoothModelCount(), "repeater", bluetoothDeviceRepeater.count);
                overlay.resetBluetoothAttemptState();
                overlay.maybeStartBluetoothOrSkip();
            }
        }

        function onModelReset() {
            if (overlay.waitingForBluetooth) {
                console.log("Startup BT: devices model reset");
                overlay.resetBluetoothAttemptState();
                overlay.maybeStartBluetoothOrSkip();
            }
        }

        function onRowsInserted() {
            if (overlay.waitingForBluetooth) {
                console.log("Startup BT: device rows inserted");
                overlay.resetBluetoothAttemptState();
                overlay.maybeStartBluetoothOrSkip();
            }
        }

        function onRowsRemoved() {
            if (overlay.waitingForBluetooth) {
                console.log("Startup BT: device rows removed");
                overlay.resetBluetoothAttemptState();
                overlay.maybeStartBluetoothOrSkip();
            }
        }
    }

    Repeater {
        id: bluetoothDeviceRepeater
        model: Bluetooth.devices

        delegate: Item {
            property var device: modelData

            Component.onCompleted: {
                console.log("Startup BT: delegate ready", index, overlay.bluetoothDeviceName(device), Boolean(device ? device.connected : false), "repeaterCount", bluetoothDeviceRepeater.count);
                overlay.maybeStartBluetoothOrSkip();
            }

            Connections {
                target: device
                ignoreUnknownSignals: true

                function onConnectedChanged() {
                    console.log("Startup BT: connected changed", overlay.bluetoothDeviceName(device), Boolean(device ? device.connected : false));
                    if (overlay.waitingForBluetooth) {
                        if (Boolean(device ? device.connected : false))
                            overlay.bluetoothConnectAttemptTimer.stop();
                        overlay.maybeStartBluetoothOrSkip();
                    }
                }

                function onNameChanged() {
                    if (overlay.waitingForBluetooth) {
                        console.log("Startup BT: name changed", overlay.bluetoothDeviceName(device));
                        overlay.resetBluetoothAttemptState();
                        overlay.maybeStartBluetoothOrSkip();
                    }
                }

                function onDeviceNameChanged() {
                    if (overlay.waitingForBluetooth) {
                        console.log("Startup BT: deviceName changed", overlay.bluetoothDeviceName(device));
                        overlay.resetBluetoothAttemptState();
                        overlay.maybeStartBluetoothOrSkip();
                    }
                }
            }
        }
    }

    MediaPlayer {
        id: player
        source: "deltarune.webm" // Local file or URL
        autoPlay: false
        videoOutput: videoOutput
        playbackRate: 1
        audioOutput: startupAudioOutput
        onPlaybackStateChanged: a => {
            console.log("Startup: playback state changed", player.playbackState);
            if (player.playbackState === MediaPlayer.StoppedState)
                overlay.finishStartup();
        }
    }

    Timer {
        id: startupDelayTimer
        interval: 1500
        repeat: false
        onTriggered: {
            console.log("Startup: startup delay elapsed, playing video");
            overlay.animationLaunchScheduled = false;
            overlay.animationStarted = true;
            player.play();
        }
    }

    Timer {
        id: bluetoothRetryTimer
        interval: 250
        running: true
        repeat: true
        onTriggered: {
            if (!overlay.waitingForBluetooth) {
                console.log("Startup BT: retry timer stopping");
                stop();
                return;
            }
            console.log("Startup BT: retry timer fired");
            overlay.maybeStartBluetoothOrSkip();
        }
    }

    Timer {
        id: bluetoothConnectAttemptTimer
        interval: overlay.bluetoothConnectAttemptMs
        running: false
        repeat: false
        onTriggered: {
            console.log("Startup BT: connect attempt timed out", overlay.bluetoothActiveTargetName);
            overlay.bluetoothConnectRequested = false;
            overlay.bluetoothActiveTargetName = "";
            overlay.bluetoothTargetAttemptIndex = Math.min(overlay.bluetoothTargetAttemptIndex + 1, overlay.bluetoothTargetNames.length);
            overlay.maybeStartBluetoothOrSkip();
        }
    }

    MediaDevices {
        id: mediaDevices
        onDefaultAudioOutputChanged: {
            console.log("Startup Audio: default output changed", mediaDevices.defaultAudioOutput.description);
            startupAudioOutput.device = mediaDevices.defaultAudioOutput;
        }
    }

    AudioOutput {
        id: startupAudioOutput
        device: mediaDevices.defaultAudioOutput
    }

    VideoOutput {
        id: videoOutput
        anchors.fill: parent
    }

    // Text {
    //     visible: overlay.waitingForBluetooth
    //     anchors.horizontalCenter: parent.horizontalCenter
    //     anchors.verticalCenter: parent.verticalCenter
    //     color: "#ffffff"
    //     font.family: "Determination Mono"
    //     font.pixelSize: 28
    //     text: "CONNECTING TO " + overlay.bluetoothTargetName.toUpperCase()
    //     z: 1
    // }

    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.NoButton
        hoverEnabled: true
        cursorShape: Qt.BlankCursor
    }
}
