#!/usr/bin/env bash
# Rofi System Menu - as rofi mode with inline submenus
# Uses ROFI_DATA for state tracking between calls
# Supports both Hyprland (Wayland) and dwm (X11)

STATE="${ROFI_DATA:-main}"
SELECTION="$1"

# ==============================================================================
# Environment Detection
# ==============================================================================
if [[ -n "${HYPRLAND_INSTANCE_SIGNATURE:-}" ]]; then
    WM="hyprland"
else
    WM="dwm"
fi

# ==============================================================================
# Helper Functions
# ==============================================================================

get_volume() { wpctl get-volume @DEFAULT_AUDIO_SINK@ 2>/dev/null | awk '{print int($2*100)}'; }
get_mic_volume() { wpctl get-volume @DEFAULT_AUDIO_SOURCE@ 2>/dev/null | awk '{print int($2*100)}'; }
is_muted() { wpctl get-volume @DEFAULT_AUDIO_SINK@ 2>/dev/null | grep -q MUTED && echo "yes" || echo "no"; }
is_mic_muted() { wpctl get-volume @DEFAULT_AUDIO_SOURCE@ 2>/dev/null | grep -q MUTED && echo "yes" || echo "no"; }
get_brightness_internal() { brightnessctl -m 2>/dev/null | cut -d',' -f4 | tr -d '%'; }
get_brightness_external() {
    if [[ "$WM" == "hyprland" ]]; then
        local val=$(busctl --user get-property rs.wl-gammarelay /outputs/DP_3 rs.wl.gammarelay Brightness 2>/dev/null | awk '{print $2}')
        echo "${val:-1}" | awk '{print int($1*100)}'
    else
        # X11: Use xrandr gamma (approximate)
        local gamma=$(xrandr --verbose | grep -A5 "DP-3" | grep "Brightness" | awk '{print $2}' 2>/dev/null)
        echo "${gamma:-1}" | awk '{print int($1*100)}'
    fi
}
get_power_profile() { powerprofilesctl get 2>/dev/null || echo "balanced"; }
get_vpn_status() {
    if systemctl is-active wg-quick-wg-vpn &>/dev/null; then echo "vpn"
    elif systemctl is-active wg-quick-wg-services &>/dev/null; then echo "services"
    else echo "off"
    fi
}

get_default_sink_id() {
    wpctl inspect @DEFAULT_AUDIO_SINK@ 2>/dev/null | head -1 | awk '{print $2}' | tr -d ','
}

get_default_source_id() {
    wpctl inspect @DEFAULT_AUDIO_SOURCE@ 2>/dev/null | head -1 | awk '{print $2}' | tr -d ','
}

get_sinks() {
    local default_id=$(get_default_sink_id)
    pw-cli list-objects Node 2>/dev/null | awk '
        /^[[:space:]]*id [0-9]+/ { id = $2; gsub(",", "", id) }
        /node.description = / { gsub(/.*node.description = "|"$/, ""); desc = $0 }
        /media.class = "Audio\/Sink"/ { print id "|" desc }
    ' | while IFS='|' read -r id desc; do
        if [[ "$id" == "$default_id" ]]; then
            echo "✓ ${desc}|${id}"
        else
            echo "${desc}|${id}"
        fi
    done
}

get_sources() {
    local default_id=$(get_default_source_id)
    pw-cli list-objects Node 2>/dev/null | awk '
        /^[[:space:]]*id [0-9]+/ { id = $2; gsub(",", "", id) }
        /node.description = / { gsub(/.*node.description = "|"$/, ""); desc = $0 }
        /media.class = "Audio\/Source"/ { print id "|" desc }
    ' | while IFS='|' read -r id desc; do
        if [[ "$id" == "$default_id" ]]; then
            echo "✓ ${desc}|${id}"
        else
            echo "${desc}|${id}"
        fi
    done
}

# ==============================================================================
# Menu Display Functions
# ==============================================================================

show_main() {
    echo -en "\0data\x1fmain\n"
    echo -en "\0keep-selection\x1ftrue\n"
    echo "󰕾  Sound"
    echo "󰃟  Brightness"
    echo "󰤨  WiFi"
    echo "󰂯  Bluetooth"
    local vpn_status=$(get_vpn_status)
    case "$vpn_status" in
        services) echo "󰒄  VPN: Services" ;;
        vpn) echo "󰛳  VPN: Full + AdBlock" ;;
        *) echo "󰲛  VPN: Off" ;;
    esac
    echo "󱐋  Power Profile"
    echo "󰐥  Power"
}

show_sound() {
    echo -en "\0data\x1fsound\n"
    echo -en "\0keep-selection\x1ftrue\n"
    local vol=$(get_volume)
    local mic=$(get_mic_volume)
    local muted=$(is_muted)
    local mic_muted=$(is_mic_muted)
    local vol_icon="󰕾"; [[ "$muted" == "yes" ]] && vol_icon="󰝟"
    local mic_icon="󰍬"; [[ "$mic_muted" == "yes" ]] && mic_icon="󰍭"

    echo "$vol_icon  Volume: ${vol}%"
    echo "󰝝  Volume +5%"
    echo "󰝞  Volume -5%"
    echo "󰓃  Output Device"
    echo "$mic_icon  Mic: ${mic}%"
    echo "󰍮  Mic +5%"
    echo "󰍯  Mic -5%"
    echo "󰍬  Input Device"
    echo "󰁍  Back"
}

show_output() {
    echo -en "\0data\x1foutput\n"
    echo -en "\0keep-selection\x1ftrue\n"
    get_sinks | while IFS='|' read -r name id; do
        echo -en "󰓃  ${name}\0info\x1f${id}\n"
    done
    echo "󰁍  Back"
}

show_input() {
    echo -en "\0data\x1finput\n"
    echo -en "\0keep-selection\x1ftrue\n"
    get_sources | while IFS='|' read -r name id; do
        echo -en "󰍬  ${name}\0info\x1f${id}\n"
    done
    echo "󰁍  Back"
}

show_brightness() {
    echo -en "\0data\x1fbrightness\n"
    echo -en "\0keep-selection\x1ftrue\n"
    local internal=$(get_brightness_internal)
    local external=$(get_brightness_external)

    echo "󰛩  Internal: ${internal}%"
    echo "󰹐  Internal +5%"
    echo "󰹏  Internal -5%"
    echo "󰍹  External: ${external}%"
    echo "󰹐  External +5%"
    echo "󰹏  External -5%"
    echo "󰁍  Back"
}

show_power_profile() {
    echo -en "\0data\x1fprofile\n"
    echo -en "\0keep-selection\x1ftrue\n"
    local current=$(get_power_profile)
    local perf="" bal="" saver=""
    [[ "$current" == "performance" ]] && perf="✓ "
    [[ "$current" == "balanced" ]] && bal="✓ "
    [[ "$current" == "power-saver" ]] && saver="✓ "

    echo "${perf}󱐌  Performance"
    echo "${bal}󰗑  Balanced"
    echo "${saver}󰌪  Power Saver"
    echo "󰢻  Edit Tuning"
    echo "󰁍  Back"
}

show_power() {
    echo -en "\0data\x1fpower\n"
    echo -en "\0keep-selection\x1ftrue\n"
    echo "󰐥  Shutdown"
    echo "󰜉  Reboot"
    echo "󰍃  Logout"
    echo "󰌾  Lock"
    echo "󰁍  Back"
}

# ==============================================================================
# Action Handlers
# ==============================================================================

handle_main() {
    case "$SELECTION" in
        *"Sound"*) show_sound ;;
        *"Brightness"*) show_brightness ;;
        *"VPN:"*)
            local vpn_status=$(get_vpn_status)
            case "$vpn_status" in
                off) busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StartUnit ss wg-quick-wg-services.service replace &>/dev/null ;;
                services)
                    busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StopUnit ss wg-quick-wg-services.service replace &>/dev/null
                    busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StartUnit ss wg-quick-wg-vpn.service replace &>/dev/null ;;
                vpn)
                    busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StopUnit ss wg-quick-wg-vpn.service replace &>/dev/null
                    busctl call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager StartUnit ss wg-quick-wg-services.service replace &>/dev/null ;;
            esac
            sleep 1
            show_main ;;
        *"WiFi"*) coproc (rofi-network-manager &); exit 0 ;;
        *"Bluetooth"*) coproc (rofi-bluetooth &); exit 0 ;;
        *"Power Profile"*) show_power_profile ;;
        *"Power"*) show_power ;;
        *) show_main ;;
    esac
}

handle_sound() {
    case "$SELECTION" in
        *"Volume:"*) wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle; show_sound ;;
        *"Volume +5%"*) wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+ -l 1.0; show_sound ;;
        *"Volume -5%"*) wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-; show_sound ;;
        *"Output Device"*) show_output ;;
        *"Mic:"*) wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle; show_sound ;;
        *"Mic +5%"*) wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%+ -l 1.0; show_sound ;;
        *"Mic -5%"*) wpctl set-volume @DEFAULT_AUDIO_SOURCE@ 5%-; show_sound ;;
        *"Input Device"*) show_input ;;
        *"Back"*) show_main ;;
        *) show_sound ;;
    esac
}

handle_output() {
    case "$SELECTION" in
        *"Back"*) show_sound ;;
        *)
            [[ -n "$ROFI_INFO" ]] && wpctl set-default "$ROFI_INFO"
            show_output
            ;;
    esac
}

handle_input() {
    case "$SELECTION" in
        *"Back"*) show_sound ;;
        *)
            [[ -n "$ROFI_INFO" ]] && wpctl set-default "$ROFI_INFO"
            show_input
            ;;
    esac
}

handle_brightness() {
    case "$SELECTION" in
        *"Internal +5%"*) brightnessctl -q set +5%; show_brightness ;;
        *"Internal -5%"*) brightnessctl -q set 5%-; show_brightness ;;
        *"External +5%"*)
            if [[ "$WM" == "hyprland" ]]; then
                current=$(get_brightness_external)
                new=$((current + 5)); [[ $new -gt 100 ]] && new=100
                val=$(echo "scale=2; $new/100" | bc)
                busctl --user set-property rs.wl-gammarelay /outputs/DP_3 rs.wl.gammarelay Brightness d "$val" 2>/dev/null
            else
                current=$(get_brightness_external)
                new=$((current + 5)); [[ $new -gt 100 ]] && new=100
                val=$(echo "scale=2; $new/100" | bc)
                xrandr --output DP-3 --brightness "$val" 2>/dev/null
            fi
            show_brightness ;;
        *"External -5%"*)
            if [[ "$WM" == "hyprland" ]]; then
                current=$(get_brightness_external)
                new=$((current - 5)); [[ $new -lt 5 ]] && new=5
                val=$(echo "scale=2; $new/100" | bc)
                busctl --user set-property rs.wl-gammarelay /outputs/DP_3 rs.wl.gammarelay Brightness d "$val" 2>/dev/null
            else
                current=$(get_brightness_external)
                new=$((current - 5)); [[ $new -lt 5 ]] && new=5
                val=$(echo "scale=2; $new/100" | bc)
                xrandr --output DP-3 --brightness "$val" 2>/dev/null
            fi
            show_brightness ;;
        *"Back"*) show_main ;;
        *) show_brightness ;;
    esac
}

handle_power_profile() {
    case "$SELECTION" in
        # systemd path watcher auto-applies power-tuning on profile change
        *"Performance"*) powerprofilesctl set performance; show_power_profile ;;
        *"Balanced"*) powerprofilesctl set balanced; show_power_profile ;;
        *"Power Saver"*) powerprofilesctl set power-saver; show_power_profile ;;
        *"Edit Tuning"*) coproc (zeditor "$HOME/NixOS/ryzenadj.nix" &); exit 0 ;;
        *"Back"*) show_main ;;
        *) show_power_profile ;;
    esac
}

handle_power() {
    case "$SELECTION" in
        *"Shutdown"*) systemctl poweroff ;;
        *"Reboot"*) systemctl reboot ;;
        *"Logout"*)
            if [[ "$WM" == "hyprland" ]]; then
                hyprctl dispatch exit
            else
                pkill -x dwm
            fi
            ;;
        *"Lock"*)
            if [[ "$WM" == "hyprland" ]]; then
                hyprlock & exit 0
            else
                slock & exit 0
            fi
            ;;
        *"Back"*) show_main ;;
        *) show_power ;;
    esac
}

# ==============================================================================
# Main Entry Point
# ==============================================================================

if [[ -z "$SELECTION" ]]; then
    case "$STATE" in
        sound) show_sound ;;
        output) show_output ;;
        input) show_input ;;
        brightness) show_brightness ;;
        profile) show_power_profile ;;
        power) show_power ;;
        *) show_main ;;
    esac
else
    case "$STATE" in
        sound) handle_sound ;;
        output) handle_output ;;
        input) handle_input ;;
        brightness) handle_brightness ;;
        profile) handle_power_profile ;;
        power) handle_power ;;
        *) handle_main ;;
    esac
fi
