import { App, Astal, Gtk } from "astal/gtk4";
import { bind, execAsync, Gio } from "astal";

import { hideWindow } from "@/lib/utils";
import Bluetooth from "gi://AstalBluetooth";
import Hyprland from "gi://AstalHyprland";

function DeviceMenu({ device, child }: { device: Bluetooth.Device, child?: JSX.Element }) {
    const menu = Gio.Menu.new();
    const copy_mac = Gio.MenuItem.new("Copy MAC address", "bt.copy_mac");
    const toggle_state = Gio.MenuItem.new(device.get_connected() ? "Disconnect" : "Connect", "bt.toggle_state");

    const action_group = Gio.SimpleActionGroup.new();

    const copy_mac_action = Gio.SimpleAction.new("copy_mac", null);
    copy_mac_action.connect("activate", () => execAsync(["wl-copy", device.address]));

    const toggle_state_action = Gio.SimpleAction.new("toggle_state", null);
    toggle_state_action.connect("activate", async () => {
		if (device.connected)
            await device.disconnect_device()
        else
            await device.connect_device()
    })

    menu.insert_item(1, copy_mac);
    menu.insert_item(2, toggle_state);

    action_group.insert(copy_mac_action);
    action_group.insert(toggle_state_action);

    return <menubutton
        menuModel={menu}
        setup={self => self.insert_action_group("bt", action_group)}
    >
        {child}
        <popover>
            <label label={"Copy MAC address"} />
            <label label={"Toggle state"} />
        </popover>
    </menubutton>;
};

export default function BluetoothWindow(_monitor_id: number) {
    const CENTER = Gtk.Align.CENTER;

    const bt = Bluetooth.get_default();
    const hypr = Hyprland.get_default();
    const devices = bind(bt, "devices");

    return <window
        name={"qs_bluetooth"}
        cssClasses={["qs_bluetooth"]}
        monitor={bind(hypr, "focusedMonitor").as(monitor => monitor.id)}
        exclusivity={Astal.Exclusivity.IGNORE}
        keymode={Astal.Keymode.EXCLUSIVE}
        application={App}
        onKeyPressed={hideWindow}
    >
        <box vertical halign={CENTER} cssClasses={["inner"]} spacing={5}>
            {devices.as(devices => devices.map(device =>
                <DeviceMenu device={device}>
                    <box cssClasses={["device", "small-padding"].concat(device.connected ? ["active"] : [])} spacing={3}>
                        <image iconName={device.icon} />
                        <label>{device.alias}</label>
                    </box>
                </DeviceMenu>
            ))}
        </box>
    </window>
}