#!/bin/bash

# Launch the Station Menu or takes a parameter to jump straight to a submenu.

# Set to true when going directly to a submenu, so we can exit directly
BACK_TO_EXIT=false

back_to() {
    local parent_menu="$1"

    if [[ $BACK_TO_EXIT == "true" ]]; then
        exit 0
    elif [[ -n $parent_menu ]]; then
        "$parent_menu"
    else
        show_main_menu
    fi
}

toggle_existing_menu() {
    if pgrep -f "walker.*--dmenu" > /dev/null; then
        walker --close > /dev/null 2>&1
        exit 0
    fi
}

menu() {
    local prompt="$1"
    local options="$2"
    local extra="$3"
    local preselect="$4"

    read -r -a args <<<"$extra"

    if [[ -n $preselect ]]; then
        local index
        index=$(echo -e "$options" | grep -nxF "$preselect" | cut -d: -f1)
        if [[ -n $index ]]; then
            args+=("-c" "$index")
        fi
    fi

    echo -e "$options" | station-launch-walker --dmenu --width 295 --minheight 1 --maxheight 630 -p "$prompt…" "${args[@]}" 2>/dev/null
}

terminal() {
    xdg-terminal-exec --app-id=org.station.terminal "$@"
}

present_terminal() {
    station-launch-floating-terminal-with-presentation $1
}

open_in_editor() {
    notify-send "Editing config file" "$1"
    station-launch-editor "$1"
}

show_trigger_menu() {
    case $(menu "Trigger" "  Capture\n  Share\n󰔎  Toggle") in
        *Capture*) show_capture_menu ;;
        *Share*) show_share_menu ;;
        *Toggle*) show_toggle_menu ;;
        *) show_main_menu ;;
    esac
}

show_capture_menu() {
    case $(menu "Capture" "  Screenshot\n  Screenrecord\n󰃉  Color") in
        *Screenshot*) station-cmd-screenshot ;;
        *Screenrecord*) show_screenrecord_menu ;;
        *Color*) pkill hyprpicker || hyprpicker -a ;;
        *) back_to show_trigger_menu ;;
    esac
}

get_webcam_list() {
    v4l2-ctl --list-devices 2>/dev/null | while IFS= read -r line; do
        if [[ $line != $'\t'* && -n $line ]]; then
            local name="$line"
            IFS= read -r device || break
            device=$(echo "$device" | tr -d '\t' | head -1)
            [[ -n $device ]] && echo "$device  $name"
        fi
    done
}

show_webcam_select_menu() {
    local devices=$(get_webcam_list)
    local count=$(echo "$devices" | grep -c . 2>/dev/null || echo 0)

    if [[ -z $devices ]] || ((count == 0)); then
        notify-send "No webcam devices found" -u critical -t 3000
        return 1
    fi

    if ((count == 1)); then
        echo "$devices" | awk '{print $1}'
    else
        menu "Select Webcam" "$devices" | awk '{print $1}'
    fi
}

show_screenrecord_menu() {
    station-cmd-screenrecord --stop-recording && exit 0

    case $(menu "Screenrecord" "  With no audio\n  With desktop audio\n  With desktop + microphone audio\n  With desktop + microphone audio + webcam") in
        *"With no audio") station-cmd-screenrecord ;;
        *"With desktop audio") station-cmd-screenrecord --with-desktop-audio ;;
        *"With desktop + microphone audio") station-cmd-screenrecord --with-desktop-audio --with-microphone-audio ;;
        *"With desktop + microphone audio + webcam")
            local device=$(show_webcam_select_menu) || {
                back_to show_capture_menu
                            return
                        }
                    station-cmd-screenrecord --with-desktop-audio --with-microphone-audio --with-webcam --webcam-device="$device"
                    ;;
                *) back_to show_capture_menu ;;
            esac
}

show_share_menu() {
    case $(menu "Share" "  Clipboard\n  File \n  Folder") in
        *Clipboard*) station-cmd-share clipboard ;;
        *File*) terminal bash -c "station-cmd-share file" ;;
        *Folder*) terminal bash -c "station-cmd-share folder" ;;
        *) back_to show_trigger_menu ;;
    esac
}

show_toggle_menu() {
    case $(menu "Toggle" "󱄄  Screensaver\n󰔎  Nightlight\n󱫖  Idle Lock\n󰍜  Top Bar\n󱂬  Workspace Layout\n  Window Gaps\n  1-Window Ratio\n󰍹  Display Scaling") in

        *Screensaver*) station-toggle-screensaver ;;
        *Nightlight*) station-toggle-nightlight ;;
        *Idle*) station-toggle-idle ;;
        *Bar*) station-toggle-waybar ;;
        *Layout*) station-hyprland-workspace-layout-toggle ;;
        *Ratio*) station-hyprland-window-single-square-aspect-toggle ;;
        *Gaps*) station-hyprland-window-gaps-toggle ;;
        *Scaling*) station-hyprland-monitor-scaling-cycle ;;
        *) back_to show_trigger_menu ;;
    esac
}

show_background_menu() {
    station-launch-walker -m menus:stationBackgroundSelector --width 800 --minheight 400
}

show_setup_menu() {
    local options="  Audio\n  Wifi\n󰂯  Bluetooth\n󱐋  Power Profile\n󰍹  Monitors"
    [[ -f ~/.config/hypr/bindings.conf ]] && options="$options\n  Keybindings"
    [[ -f ~/.config/hypr/input.conf ]] && options="$options\n  Input"
    options="$options\n  Config"

    case $(menu "Setup" "$options") in
        *Audio*) station-launch-audio ;;
        *Wifi*) station-launch-wifi ;;
        *Bluetooth*) station-launch-bluetooth ;;
        *Power*) show_setup_power_menu ;;
        *Monitors*) open_in_editor ~/.config/hypr/monitors.conf ;;
        *Keybindings*) open_in_editor ~/.config/hypr/bindings.conf ;;
        *Input*) open_in_editor ~/.config/hypr/input.conf ;;
        *Config*) show_setup_config_menu ;;
        *) show_main_menu ;;
    esac
}

show_setup_power_menu() {
    profile=$(menu "Power Profile" "$(station-powerprofiles-list)" "" "$(powerprofilesctl get)")

    if [[ $profile == "CNCLD" || -z $profile ]]; then
        back_to show_setup_menu
    else
        powerprofilesctl set "$profile"
    fi
}

show_setup_config_menu() {
    case $(menu "Setup" "  Defaults\n  Hyprland\n  Hypridle\n  Hyprlock\n  Hyprsunset\n  Swayosd\n󰌧  Walker\n󰍜  Waybar\n󰞅  XCompose") in
        *Defaults*) open_in_editor ~/.config/uwsm/default ;;
        *Hyprland*) open_in_editor ~/.config/hypr/hyprland.conf ;;
        *Hypridle*) open_in_editor ~/.config/hypr/hypridle.conf && station-restart-app hypridle ;;
        *Hyprlock*) open_in_editor ~/.config/hypr/hyprlock.conf ;;
        *Hyprsunset*) open_in_editor ~/.config/hypr/hyprsunset.conf && station-restart-app hyprsunset ;;
        *Swayosd*) open_in_editor ~/.config/swayosd/config.toml && station-restart-app swayosd-server ;;
        *Walker*) open_in_editor ~/.config/walker/config.toml && station-restart-walker ;;
        *Waybar*) open_in_editor ~/.config/waybar/config.jsonc && station-restart-app waybar ;;
        *XCompose*) open_in_editor ~/.config/xcompose && station-restart-app fcitx5 --disable notificationitem ;;
        *) show_setup_menu ;;
    esac
}

show_update_menu() {
    case $(menu "Update" "  Station\n  Process\n󰇅  Hardware\n  Firmware\n  Password\n  Timezone\n  Time") in
        *Station*) present_terminal station-update-system ;;
        *Process*) show_update_process_menu ;;
        *Hardware*) show_update_hardware_menu ;;
        *Firmware*) present_terminal station-update-firmware ;;
        *Timezone*) present_terminal station-tz-select ;;
        *Time*) present_terminal station-update-time ;;
        *Password*) show_update_password_menu ;;
        *) show_main_menu ;;
    esac
}

show_update_process_menu() {
    case $(menu "Restart" "  Hypridle\n  Hyprsunset\n  Swayosd\n󰌧  Walker\n󰍜  Waybar") in
        *Hypridle*) station-restart-app hypridle ;;
        *Hyprsunset*) station-restart-app hyprsunset ;;
        *Swayosd*) station-restart-app swayosd-server ;;
        *Walker*) station-restart-walker ;;
        *Waybar*) station-restart-app waybar ;;
        *) show_update_menu ;;
    esac
}

show_update_hardware_menu() {
    case $(menu "Restart" "  Audio\n󱚾  Wi-Fi\n󰂯  Bluetooth") in
        *Audio*) present_terminal station-restart-pipewire ;;
        *Wi-Fi*) present_terminal station-restart-wifi ;;
        *Bluetooth*) present_terminal station-restart-bluetooth ;;
        *) show_update_menu ;;
    esac
}

show_update_password_menu() {
    case $(menu "Update Password" "  Drive Encryption\n  User") in
        *Drive*) present_terminal station-drive-set-password ;;
        *User*) present_terminal passwd ;;
        *) show_update_menu ;;
    esac
}

show_system_menu() {
    local options="󱄄  Screensaver\n  Lock\n󰒲  Suspend"
    station-hibernation-available && options="$options\n󰤁  Hibernate"
    options="$options\n󰍃  Logout\n󰜉  Restart\n󰐥  Shutdown"
    echo $options

    case $(menu "System" "$options") in
        *Screensaver*) station-launch-screensaver force ;;
        *Lock*) station-lock-screen ;;
        *Suspend*) systemctl suspend ;;
        *Hibernate*) systemctl hibernate ;;
        *Logout*) station-system-logout ;;
        *Restart*) station-system-reboot ;;
        *Shutdown*) station-system-shutdown ;;
        *) back_to show_main_menu ;;
    esac
}

show_main_menu() {
    go_to_menu "$(menu "Go" "󰀻  Apps\n󱓞  Trigger\n  Setup\n  Update\n  System")"
}

go_to_menu() {
    case "${1,,}" in
        *apps*) walker -p "Launch…" ;;
        *trigger*) show_trigger_menu ;;
        *share*) show_share_menu ;;
        *background*) show_background_menu ;;
        *setup*) show_setup_menu ;;
        *update*) show_update_menu ;;
        *system*) show_system_menu ;;
        *capture*) show_capture_menu ;;
        *toggle*) show_toggle_menu ;;
        *screenrecord*) show_screenrecord_menu ;;
    esac
}

toggle_existing_menu

if [[ -n $1 ]]; then
    BACK_TO_EXIT=true
    go_to_menu "$1"
else
    show_main_menu
fi
