// ── violet-chaton v2 — AGS config ───────────────────────────────────────────
// Barre + OSD + Launcher + Notifications
// API: AGS v1.8.2 (.hook/.bind/.poll — no connections)

const audio = await Service.import("audio");
const battery = await Service.import("battery");
const network = await Service.import("network");
const systemtray = await Service.import("systemtray");
const mpris = await Service.import("mpris");
const notifications = await Service.import("notifications");
const applications = await Service.import("applications");

// ── Compositor detection ────────────────────────────────────────────────────
const compositor = (() => {
    const session = Utils.exec("bash -c 'echo $XDG_CURRENT_DESKTOP'").trim();
    if (session.includes("Hyprland")) return "hyprland";
    if (session.includes("COSMIC")) return "cosmic";
    return "unknown";
})();

print(`[violet-chaton] compositor: ${compositor}`);

// ══════════════════════════════════════════════════════════════════════════════
//  BAR
// ══════════════════════════════════════════════════════════════════════════════

const Separator = () => Widget.Label({ className: "separator", label: "│" });

const Clock = () => Widget.Label({ className: "clock" })
    .poll(1000, (self) => { self.label = Utils.exec("date +%H:%M"); });

const DateWidget = () => Widget.Label({ className: "date" })
    .poll(60000, (self) => { self.label = Utils.exec("date '+%a %d %b'"); });

const CPU = () => Widget.Label({ className: "cpu" })
    .poll(2000, (self) => {
        const usage = Math.round(
            Number(Utils.exec(['bash', '-c', "top -bn1 | awk '/^%Cpu/ {print 100-$8}'"]))
        );
        self.label = `󰻠 ${usage}%`;
        self.toggleClassName("warning", usage > 70);
        self.toggleClassName("critical", usage > 90);
    });

const RAM = () => Widget.Label({ className: "ram" })
    .poll(2000, (self) => {
        const used = Utils.exec(['bash', '-c', "free -m | awk '/^Mem:/ {printf \"%.1f\", $3/1024}'"]);
        const total = Utils.exec(['bash', '-c', "free -m | awk '/^Mem:/ {printf \"%.1f\", $2/1024}'"]);
        const pct = Math.round((parseFloat(used) / parseFloat(total)) * 100);
        self.label = `󰑭 ${used}G`;
        self.toggleClassName("warning", pct > 70);
        self.toggleClassName("critical", pct > 90);
    });

const Network = () => Widget.Label({ className: "network" })
    .hook(network, (self) => {
        if (network.primary === "wifi") {
            const wifi = network.wifi;
            self.label = `󰤨 ${wifi?.ssid || ""}`;
            self.toggleClassName("wifi", true);
            self.toggleClassName("disconnected", false);
        } else if (network.primary === "wired") {
            self.label = "󰈀 Eth";
            self.toggleClassName("wifi", false);
            self.toggleClassName("disconnected", false);
        } else {
            self.label = "󰤮 ";
            self.toggleClassName("disconnected", true);
        }
    });

const Volume = () => Widget.Button({
    className: "volume",
    onClicked: () => { audio.speaker.isMuted = !audio.speaker.isMuted; },
    child: Widget.Label()
        .hook(audio, (self) => {
            const vol = Math.round((audio.speaker?.volume || 0) * 100);
            const muted = audio.speaker?.isMuted;
            const icon = muted ? "󰝟" : vol > 66 ? "󰕾" : vol > 33 ? "󰖀" : "󰕿";
            self.label = `${icon} ${vol}%`;
            self.parent?.toggleClassName("muted", muted);
        }, "speaker-changed"),
});

const Battery = () => Widget.Label({
    className: "battery",
    visible: battery.bind("available"),
}).hook(battery, (self) => {
    const pct = battery.percent;
    const charging = battery.charging;
    const icon = charging ? "󰂄" : pct > 80 ? "󰁹" : pct > 60 ? "󰂀" :
                 pct > 40 ? "󰁾" : pct > 20 ? "󰁻" : "󰂎";
    self.label = `${icon} ${pct}%`;
    self.toggleClassName("charging", charging);
    self.toggleClassName("low", pct <= 20 && !charging);
    self.toggleClassName("warning", pct <= 30 && !charging);
});

const Media = () => Widget.Label({ className: "media" })
    .hook(mpris, (self) => {
        const player = mpris.players[0];
        if (!player) {
            self.visible = false;
            return;
        }
        self.visible = true;
        const artist = player.trackArtists?.join(", ") || "";
        const title = player.trackTitle || "";
        const icon = player.playBackStatus === "Playing" ? " " : " ";
        self.label = `${icon}${artist ? artist + " — " : ""}${title}`.slice(0, 50);
        self.toggleClassName("paused", player.playBackStatus !== "Playing");
    });

const SysTray = () => Widget.Box({
    className: "systray",
    children: systemtray.bind("items").as((items) =>
        items.map((item) =>
            Widget.Button({
                child: Widget.Icon({ icon: item.bind("icon"), size: 16 }),
                tooltipMarkup: item.bind("tooltip-markup"),
                onPrimaryClick: (_, event) => item.activate(event),
                onSecondaryClick: (_, event) => item.openMenu(event),
            })
        )
    ),
});

const LauncherBtn = () => Widget.Button({
    className: "launcher-btn",
    label: "󱄅",
    onClicked: () => App.toggleWindow("launcher"),
});

const PowerBtn = () => Widget.Button({
    className: "power-btn",
    label: "⏻",
    onClicked: () => Utils.exec("bash -c 'systemctl poweroff'"),
});

const Workspaces = () => {
    if (compositor !== "hyprland") return Widget.Box({});
    // Hyprland not running — return empty
    return Widget.Box({});
};

const Bar = (monitor) => Widget.Window({
    name: `bar-${monitor}`,
    monitor,
    anchor: ["top", "left", "right"],
    exclusivity: "exclusive",
    className: "bar",
    child: Widget.CenterBox({
        startWidget: Widget.Box({
            className: "modules-left",
            children: [
                LauncherBtn(),
                Separator(),
                Workspaces(),
                CPU(),
                RAM(),
            ],
        }),
        centerWidget: Widget.Box({
            className: "modules-center",
            children: [
                Media(),
            ],
        }),
        endWidget: Widget.Box({
            className: "modules-right",
            hpack: "end",
            children: [
                Network(),
                Separator(),
                Volume(),
                Separator(),
                Battery(),
                Separator(),
                DateWidget(),
                Clock(),
                Separator(),
                SysTray(),
                Separator(),
                PowerBtn(),
            ],
        }),
    }),
});

// ══════════════════════════════════════════════════════════════════════════════
//  OSD
// ══════════════════════════════════════════════════════════════════════════════

const VolumeOSD = () => {
    const icon = Widget.Label({ className: "icon" });
    const progress = Widget.ProgressBar();
    const label = Widget.Label({ className: "label" });

    return Widget.Box({
        className: "osd",
        children: [icon, progress, label],
    }).hook(audio, (self) => {
        const vol = audio.speaker?.volume || 0;
        const muted = audio.speaker?.isMuted;
        icon.label = muted ? "󰝟" : vol > 0.66 ? "󰕾" : vol > 0.33 ? "󰖀" : "󰕿";
        progress.value = vol;
        label.label = `${Math.round(vol * 100)}%`;
    }, "speaker-changed");
};

const BrightnessOSD = () => {
    const icon = Widget.Label({ className: "icon", label: "󰃞" });
    const progress = Widget.ProgressBar();
    const label = Widget.Label({ className: "label" });

    const getBrightness = () => {
        try {
            const max = Number(Utils.exec("brightnessctl max"));
            const cur = Number(Utils.exec("brightnessctl get"));
            return max > 0 ? cur / max : 0;
        } catch {
            return 0;
        }
    };

    return Widget.Box({
        className: "osd",
        children: [icon, progress, label],
    }).poll(500, (self) => {
        const val = getBrightness();
        progress.value = val;
        label.label = `${Math.round(val * 100)}%`;
    });
};

const OSD = (monitor) => [
    Widget.Window({
        name: `osd-volume-${monitor}`,
        monitor,
        anchor: ["bottom"],
        layer: "overlay",
        visible: false,
        child: VolumeOSD(),
    }),
    Widget.Window({
        name: `osd-brightness-${monitor}`,
        monitor,
        anchor: ["bottom"],
        layer: "overlay",
        visible: false,
        child: BrightnessOSD(),
    }),
];

// ══════════════════════════════════════════════════════════════════════════════
//  LAUNCHER
// ══════════════════════════════════════════════════════════════════════════════

const AppItem = (app) => Widget.Button({
    className: "app-item",
    onClicked: () => {
        app.launch();
        App.closeWindow("launcher");
    },
    child: Widget.Box({
        children: [
            Widget.Icon({ icon: app.iconName || "application-x-executable", size: 24 }),
            Widget.Box({
                vertical: true,
                children: [
                    Widget.Label({ label: app.name, xalign: 0, truncate: "end" }),
                    Widget.Label({
                        label: app.description || "",
                        xalign: 0,
                        truncate: "end",
                        css: "color: #716686; font-size: 11px; font-weight: normal;",
                    }),
                ],
            }),
        ],
    }),
});

const Launcher = (monitor) => {
    let apps = applications.list;

    const list = Widget.Box({ vertical: true, spacing: 2 });

    const entry = Widget.Entry({
        className: "search",
        placeholderText: "Rechercher...",
        onAccept: () => {
            const first = apps[0];
            if (first) {
                first.launch();
                App.closeWindow("launcher");
            }
        },
        onChange: ({ text }) => {
            apps = applications.query(text || "");
            list.children = apps.slice(0, 12).map(AppItem);
            if (apps.length === 0) {
                list.children = [Widget.Label({
                    className: "no-results",
                    label: "Aucun resultat",
                })];
            }
        },
    });

    return Widget.Window({
        name: "launcher",
        monitor,
        anchor: ["top"],
        layer: "overlay",
        visible: false,
        keymode: "exclusive",
        setup: (self) => {
            self.keybind("Escape", () => App.closeWindow("launcher"));
            self.hook(App, (_, name, visible) => {
                if (name === "launcher" && visible) {
                    entry.text = "";
                    apps = applications.list;
                    list.children = apps.slice(0, 12).map(AppItem);
                    entry.grab_focus();
                }
            });
        },
        child: Widget.Box({
            className: "launcher",
            vertical: true,
            children: [
                Widget.Scrollable({
                    hscroll: "never",
                    vscroll: "automatic",
                    css: "min-height: 400px;",
                    child: list,
                }),
                entry,
            ],
        }),
    });
};

// ══════════════════════════════════════════════════════════════════════════════
//  NOTIFICATIONS
// ══════════════════════════════════════════════════════════════════════════════

notifications.popupTimeout = 5000;
notifications.cacheActions = true;

const NotificationIcon = (notif) => {
    if (notif.image) {
        return Widget.Box({
            css: `
                min-width: 48px; min-height: 48px;
                background-image: url("${notif.image}");
                background-size: cover;
                background-position: center;
                border-radius: 8px;
                margin-right: 10px;
            `,
        });
    }
    return Widget.Icon({
        icon: notif.appIcon || notif.appEntry || "dialog-information",
        size: 36,
        css: "margin-right: 10px;",
    });
};

const Notification = (notif) => Widget.Box({
    className: `notification ${notif.urgency}`,
    vertical: true,
    children: [
        Widget.Box({
            children: [
                NotificationIcon(notif),
                Widget.Box({
                    vertical: true,
                    hexpand: true,
                    children: [
                        Widget.Box({
                            children: [
                                Widget.Label({
                                    className: "title",
                                    label: notif.summary,
                                    xalign: 0,
                                    hexpand: true,
                                    truncate: "end",
                                }),
                                Widget.Label({
                                    className: "time",
                                    label: new Date(notif.time * 1000)
                                        .toLocaleTimeString("fr-FR", {
                                            hour: "2-digit",
                                            minute: "2-digit",
                                        }),
                                }),
                                Widget.Button({
                                    className: "close-btn",
                                    label: "✕",
                                    onClicked: () => notif.close(),
                                }),
                            ],
                        }),
                        Widget.Label({
                            className: "app-name",
                            label: notif.appName || "",
                            xalign: 0,
                        }),
                    ],
                }),
            ],
        }),
        ...(notif.body ? [Widget.Label({
            className: "body",
            label: notif.body,
            xalign: 0,
            wrap: true,
            useMarkup: true,
        })] : []),
        ...(notif.actions.length > 0 ? [Widget.Box({
            className: "actions",
            children: notif.actions.map((action) =>
                Widget.Button({
                    label: action.label,
                    onClicked: () => notif.invoke(action.id),
                })
            ),
        })] : []),
    ],
});

const Notifications = (monitor) => Widget.Window({
    name: `notifications-${monitor}`,
    monitor,
    anchor: ["top", "right"],
    layer: "overlay",
    child: Widget.Box({
        vertical: true,
        css: "min-width: 350px;",
        children: notifications.bind("popups").as((popups) =>
            popups.map(Notification)
        ),
    }),
});

// ══════════════════════════════════════════════════════════════════════════════
//  EXPORT
// ══════════════════════════════════════════════════════════════════════════════

export default {
    style: `${App.configDir}/css/style.css`,
    windows: [
        Bar(0),
        ...OSD(0),
        Launcher(0),
        Notifications(0),
    ],
};
