import { Arrow, Menu } from "../ToggleButton.js"
import { dependencies, icon, sh } from "../../../lib/utils.js"
import icons from "../../../lib/icons.js"
const audio = await Service.import("audio")

const VolumeIndicator = (type = "speaker") => Widget.Button({
  vpack: "center",
  on_clicked: () => audio[type].is_muted = !audio[type].is_muted,
  child: Widget.Icon({
    icon: audio[type].bind("icon_name")
      .as(i => icon(i || "", icons.audio.mic.high)),
    tooltipText: audio[type].bind("volume")
      .as(vol => `Volume: ${Math.floor(vol * 100)}%`),
  }),
})

const VolumeSlider = (type = "speaker") => Widget.Slider({
  hexpand: true,
  draw_value: false,
  on_change: ({ value, dragging }) => dragging && (audio[type].volume = value),
  value: audio[type].bind("volume"),
})

export const Volume = () => Widget.Box({
  class_name: "volume",
  children: [
    VolumeIndicator("speaker"),
    VolumeSlider("speaker"),
    Widget.Box({
      vpack: "center",
      child: Arrow("sink-selector"),
    }),
    Widget.Box({
      vpack: "center",
      child: Arrow("app-mixer"),
      visible: audio.bind("apps").as(a => a.length > 0),
    }),
  ],
})

export const Microhone = () => Widget.Box({
  class_name: "slider horizontal",
  visible: audio.bind("recorders").as(a => a.length > 0),
  children: [
    VolumeIndicator("microphone"),
    VolumeSlider("microphone"),
  ],
})

const MixerItem = (stream) => Widget.Box(
  {
    hexpand: true,
    class_name: "mixer-item horizontal",
  },
  Widget.Icon({
    tooltip_text: stream.bind("name").as(n => n || ""),
    icon: stream.bind("name").as(n => {
      return Utils.lookUpIcon(n || "")
        ? (n || "")
        : icons.fallback.audio
    }),
  }),
  Widget.Box(
    { vertical: true },
    Widget.Label({
      xalign: 0,
      truncate: "end",
      max_width_chars: 28,
      label: stream.bind("description").as(d => d || ""),
    }),
    Widget.Slider({
      hexpand: true,
      draw_value: false,
      value: stream.bind("volume"),
      on_change: ({ value }) => stream.volume = value,
    }),
  ),
)

const SinkItem = (stream) => Widget.Button({
  hexpand: true,
  on_clicked: () => audio.speaker = stream,
  child: Widget.Box({
    children: [
      Widget.Icon({
        icon: icon(stream.icon_name || "", icons.fallback.audio),
        tooltip_text: stream.icon_name || "",
      }),
      Widget.Label((stream.description || "").split(" ").slice(0, 4).join(" ")),
      Widget.Icon({
        icon: icons.ui.tick,
        hexpand: true,
        hpack: "end",
        visible: audio.speaker.bind("stream").as(s => s === stream.stream),
      }),
    ],
  }),
})

const SettingsButton = () => Widget.Button({
  on_clicked: () => {
    if (dependencies("pavucontrol"))
      sh("pavucontrol")
  },
  hexpand: true,
  child: Widget.Box({
    children: [
      Widget.Icon(icons.ui.settings),
      Widget.Label("Settings"),
    ],
  }),
})

export const AppMixer = () => Menu({
  name: "app-mixer",
  icon: icons.audio.mixer,
  title: "App Mixer",
  content: [
    Widget.Box({
      vertical: true,
      class_name: "vertical mixer-item-box",
      children: audio.bind("apps").as(a => a.map(MixerItem)),
    }),
    Widget.Separator(),
    SettingsButton(),
  ],
})

export const SinkSelector = () => Menu({
  name: "sink-selector",
  icon: icons.audio.type.headset,
  title: "Sink Selector",
  content: [
    Widget.Box({
      vertical: true,
      children: audio.bind("speakers").as(a => a.map(SinkItem)),
    }),
    Widget.Separator(),
    SettingsButton(),
  ],
})
