import { bind, interval, readFile, timeout, writeFile } from "astal";
import { Gtk } from "astal/gtk4";
import AstalBluetooth from "gi://AstalBluetooth";
import BTDevice from "./Device";
const ALIGN = Gtk.Align;

const bt = AstalBluetooth.get_default();

const BluetoothModule = () => {
    const picker = BluetoothPicker();

    const openBTPicker = () => {
        try {
            bt.adapter.start_discovery();
        } catch (e) {
            printerr(e);
        }
        picker.popup();
    };

    return (
        <box>
            <button
                cssClasses={bind(bt, "isPowered").as(powered =>
                    powered
                        ? ["toggle-button", "toggle-on"]
                        : ["toggle-button"],
                )}
                onClicked={() => {
                    try {
                        bt.adapter.set_powered(!bt.adapter.get_powered())
                    } catch (_) { }
                }}
                child={
                    <box vertical>
                        <label
                            cssClasses={["title-2"]}
                            label={"Bluetooth"}
                            halign={ALIGN.CENTER}
                            valign={ALIGN.CENTER}
                        ></label>
                        <box halign={ALIGN.CENTER} valign={ALIGN.CENTER}>
                            <label
                                visible={bind(bt, "isPowered").as(
                                    p => !p,
                                )}
                                label="Disabled"
                            ></label>
                            <label
                                visible={bind(bt, "isPowered")}
                                label={bind(bt, "devices").as(devices => {
                                    let count = 0;
                                    devices.forEach(device => {
                                        if (device.connected) {
                                            count++;
                                        }
                                    });
                                    return `On (${count} ${count === 1 ? "client" : "clients"} connected)`;
                                })}
                            ></label>
                        </box>
                        <label></label>
                    </box>
                }
            ></button>
            <button
                cssClasses={["actions-button"]}
                visible={bind(bt, "isPowered")}
                child={
                    <box>
                        <image iconName={"arrow-right-symbolic"}></image>
                        {picker}
                    </box>
                }
                tooltipText={"View available devices"}
                onClicked={() => openBTPicker()}
            ></button>
        </box>
    );
};

const BluetoothPickerList = () => {
    let btEnableState = false;

    try {
        btEnableState = readFile("./btconf") === "true" ? true : false;
    } catch (_) { }

    if (bt.get_adapter()) {
        print('Setting BT state to ' + btEnableState);
        bt.adapter.set_powered(btEnableState);
    } else {
        timeout(5000, () => {
            if (bt.get_adapter()) {
                print('Setting BT state to ' + btEnableState);
                bt.adapter.set_powered(btEnableState);
            } else {
                timeout(5000, () => {
                    try {
                        bt.adapter.set_powered(btEnableState);
                    } catch (_) { }
                })
            }
        })
    }

    const updateState = () => {
        btEnableState = !btEnableState;
        writeFile("./btconf", "" + btEnableState);
    };

    return (
        <box
            vertical
            onDestroy={() => {
                try {
                    bt.adapter.stop_discovery()
                } catch (_) { }
            }}
            cssClasses={["popover-box"]}
        >
            <label cssClasses={["title"]} label={"Bluetooth"}></label>
            <Gtk.Separator marginTop={3} marginBottom={5}></Gtk.Separator>
            <centerbox
                startWidget={<label label={"Turn on at startup"}></label>}
                endWidget={
                    <switch
                        valign={ALIGN.END}
                        halign={ALIGN.END}
                        active={btEnableState}
                        onButtonPressed={() => updateState()}
                    ></switch>
                }
            ></centerbox>
            <label
                marginTop={10}
                label={"Connected & Trusted devices"}
                cssClasses={["title-2"]}
            ></label>
            <Gtk.Separator marginTop={3} marginBottom={5}></Gtk.Separator>
            <box vertical cssClasses={["devices-list"]}>
                {bind(bt, "devices").as(devices => {
                    return devices
                        .filter(device => {
                            if (device.get_connected() || device.get_paired()) {
                                return device;
                            }
                        })
                        .map(device => {
                            return <BTDevice device={device}></BTDevice>;
                        });
                })}
            </box>
            <label
                visible={bind(bt, "devices").as(devices => {
                    return (
                        devices.filter(device => {
                            if (device.get_connected() || device.get_paired()) {
                                return device;
                            }
                        }).length === 0
                    );
                })}
                label={"No connected / trusted devices"}
                cssClasses={["bt-no-found", "bt-conn-list"]}
            ></label>
            <label
                label={"Discovered bluetooth devices"}
                cssClasses={["title-2"]}
            ></label>
            <Gtk.Separator marginBottom={5} marginTop={3}></Gtk.Separator>
            <box vertical>
                {bind(bt, "devices").as(devices => {
                    return devices
                        .filter(data => {
                            if (!data.get_connected() && !data.get_paired()) {
                                return data;
                            }
                        })
                        .map(device => {
                            return <BTDevice device={device}></BTDevice>;
                        });
                })}
            </box>
            <label
                visible={bind(bt, "devices").as(devices => {
                    return (
                        devices.filter(device => {
                            if (
                                !device.get_connected() &&
                                !device.get_paired()
                            ) {
                                return device;
                            }
                        }).length === 0
                    );
                })}
                label={"No discovered devices"}
                cssClasses={["bt-no-found"]}
            ></label>
        </box>
    );
};

const BluetoothPicker = () => {
    const popover = new Gtk.Popover();

    popover.set_child(BluetoothPickerList());
    popover.connect("closed", () => {
        try {
            bt.adapter.stop_discovery();
        } catch (e) {
            printerr(e);
        }
    });

    return popover;
};

export default {
    BluetoothModule,
};
