import { Astal, Gtk, Gdk } from "astal/gtk4";
import { Variable, GLib, bind } from "astal";
import Battery from "gi://AstalBattery";
import Wp from "gi://AstalWp";
import Network from "gi://AstalNetwork";
import Hyprland from "gi://AstalHyprland";

function Wifi() {
  const network = Network.get_default();
  const wifi = bind(network, "wifi");

  return (
    <box visible={wifi.as(Boolean)}>
      {wifi.as(
        (wifi) =>
          wifi && (
            <image cssClasses={["Wifi"]} iconName={bind(wifi, "iconName")} />
          ),
      )}
    </box>
  );
}

function Audio() {
  const speaker = Wp.get_default()?.audio.defaultSpeaker!;

  return (
    <box cssClasses={["Audio"]}>
      <image iconName={bind(speaker, "volumeIcon")} />
    </box>
  );
}

function BatteryLevel() {
  const bat = Battery.get_default();

  return (
    <box cssClasses={["Battery"]} visible={bind(bat, "isPresent")}>
      <image iconName={bind(bat, "batteryIconName")} />
      <label
        label={bind(bat, "percentage").as((p) => `${Math.floor(p * 100)} %`)}
      />
    </box>
  );
}

function Time({ format = "%H:%M - %A %e." }) {
  const time = Variable<string>("").poll(
    1000,
    () => GLib.DateTime.new_now_local().format(format)!,
  );

  return (
    <box cssClasses={["Time"]}>
      <menubutton>
        <label label={time()} />
        <popover hasArrow={false}>
          <Gtk.Calendar />
        </popover>
      </menubutton>
    </box>
  );
}

function QuickSettings() {
  return (
    <box cssClasses={["QuickSettings"]}>
      <menubutton>
        <box>
          <Audio />
          <Wifi />
          <BatteryLevel />
        </box>
        <popover hasArrow={false}></popover>
      </menubutton>
    </box>
  );
}

function Workspaces() {
  const hypr = Hyprland.get_default();

  return (
    <box cssClasses={["Workspaces"]}>
      {bind(hypr, "workspaces").as((wss) =>
        wss
          .filter((ws) => !(ws.id >= -99 && ws.id <= -2)) // filter out special workspaces
          .sort((a, b) => a.id - b.id)
          .map((ws) => (
            <button
              valign={Gtk.Align.CENTER}
              cssClasses={bind(hypr, "focusedWorkspace").as((fw) =>
                ws === fw ? ["focused"] : [""],
              )}
              onClicked={() => ws.focus()}
            ></button>
          )),
      )}
    </box>
  );
}
export default function Bar(monitor: Gdk.Monitor) {
  const { TOP, LEFT, RIGHT } = Astal.WindowAnchor;

  return (
    <window
      visible
      namespace={"bar"}
      cssClasses={["Bar"]}
      gdkmonitor={monitor}
      exclusivity={Astal.Exclusivity.EXCLUSIVE}
      anchor={TOP | LEFT | RIGHT}
    >
      <centerbox shrinkCenterLast>
        <box hexpand halign={Gtk.Align.START}>
          <Workspaces />
        </box>
        <box halign={Gtk.Align.CENTER}>
          <Time />
        </box>
        <box hexpand halign={Gtk.Align.END}>
          <QuickSettings />
        </box>
      </centerbox>
    </window>
  );
}
