#!/bin/bash
# =============================================================================
# hyprlua.sh — HyprLua Desktop Environment installer (Lua-based config)
# =============================================================================
# Part of the Dotfiles setup system for Arch Linux.
#
# HyprLua is the primary / recommended Hyprland variant in this Dotfiles repo.
# It uses a Lua configuration file (hyprland.lua) instead of hyprlang (.conf),
# enabling programmatic config generation, per-device overrides via Lua modules,
# and more maintainable keybind/rule definitions.
#
# Differences from hyprland.sh (the legacy .conf variant):
#   - Config source paths point to desktopenvs/hyprlua/
#   - Device-specific overrides live in ~/.config/hypr/usr/ (Lua modules
#     loaded via require("usr.*")), not at ~/.config/ root
#   - Adds python-opencv + v4l-utils for the webcam presence-detection daemon
#   - Tablet mode also installs evdev-right-click-emulation from AUR
#   - gsettings sets prefer-dark globally (relevant for GTK apps under Hyprland)
#   - qt6ct is NOT installed (hyprlua dropped it from the package list)
#   - Adds --needed flag to yay to skip already-installed AUR packages
#
# High-level install flow:
#   1.  System update + Flatpak
#   2.  pacman packages (compositor, audio, networking, tools, fonts, webcam)
#   3.  systemd service enablement
#   4.  AUR packages via yay
#   5.  EWW bar (form-factor selection + Rust compilation)
#   6.  Themes, terminal symlink, SSH askpass, dark-mode preference
#   7.  Nordzy left-hand cursor theme
#   8.  Bluetooth / iwd services
#   9.  Config file deployment (hyprlua source tree)
#  10.  Wallpaper + resource files
#  11.  Python venv for helper scripts
#  12.  Udiskie tray-icon symlink fix
#  13.  config-updater symlinks + apply-theme.sh
#
# Prerequisites: internet access, yay (AUR helper), rustup, git, curl, cargo.
# =============================================================================

# Exit immediately on any error — partial DE installs leave a broken system.
set -e

# Load shared logging helpers (log, warn, err) from the setup library.
source "$(dirname "${BASH_SOURCE[0]}")/../lib/logging.sh"

log "Starting HyprLua installer (Lua-based config)..."

# ---------------------------------------------------------------------------
# 1. Update system and install Flatpak
# ---------------------------------------------------------------------------
# Full system upgrade before package installs to avoid Arch partial-upgrade
# issues (library ABI mismatches between un-upgraded and newly installed pkgs).
log "Updating system and installing Flatpak..."
sudo pacman -Syu --noconfirm --needed flatpak

# ---------------------------------------------------------------------------
# 2. Install required packages
# ---------------------------------------------------------------------------
log "Installing required packages..."
# Packages live in an array so each can carry an inline comment. A single
# backslash-continued `pacman` command cannot: bash treats the first inline
# comment as the end of the command, silently dropping every later package
# (which then get run as shell commands and abort under `set -e`).
HYPRLUA_PACKAGES=(
    hyprland              # Wayland compositor / window manager
    hyprcursor            # hardware-accelerated cursor rendering for Hyprland
    wl-clipboard          # wl-copy / wl-paste; Wayland clipboard CLI tools
    hyprpaper             # wallpaper utility with per-monitor support
    hyprlock              # GPU-accelerated screen locker (Hyprland-native)
    wofi                  # Wayland application launcher (rofi alternative)
    kitty                 # GPU-accelerated terminal (default in this setup)
    dunst                 # lightweight, scriptable notification daemon

    nwg-look              # GTK/cursor/icon theme picker for wlroots sessions

    # astal-menu popup control centre (replaces nwg-dock + nwg-drawer)
    python-gobject        # PyGObject: GTK4 + Astal libs from Python
    gtk4                  # GTK4 toolkit (the menu's frontend)
    gtk4-layer-shell      # wlr-layer-shell for GTK4 (the popup surface)
    libshumate            # GTK4 OpenStreetMap widget (Location quad)
    bluez-utils           # bluetoothctl + bluez CLI (Bluetooth quad fallbacks)
    iproute2 curl jq      # ip/ss, HTTP fetches, JSON (Network/Weather backends)
    traceroute            # path trace to 1.1.1.1 for the Location quad's IP geolocation

    # Build toolchain required for EWW (Rust) and AUR package compilation
    python cmake meson cpio pkgconf ruby-pkg-config

    hyprsunset            # blue-light filter / night-mode daemon
    hypridle              # idle daemon triggering lock/suspend after inactivity
    ksshaskpass           # Qt SSH passphrase dialog registered as ssh-askpass

    nm-connection-editor   # GTK editor for NetworkManager connection profiles
    network-manager-applet # tray applet showing network connection status
    blueman                # GTK Bluetooth manager with tray icon support
    bluez                  # core Linux Bluetooth protocol stack

    pipewire              # modern audio/video routing daemon (replaces PulseAudio)
    alsa-utils            # low-level ALSA CLI tools (amixer, aplay, arecord)
    firefox               # web browser
    greetd-tuigreet       # TUI login greeter (text-based, no GPU requirement)

    grim                  # Wayland screenshot capture tool
    slurp                 # interactive rectangular region selector for screenshots
    gst-plugin-pipewire   # GStreamer plugin routing through PipeWire
    imagemagick           # image processing toolkit for screenshot effects

    nerd-fonts            # all Nerd Font families (icon glyphs in EWW bar)
    otf-font-awesome      # Font Awesome glyph set for bar and notifications

    # Compatibility shims letting ALSA, JACK, and PulseAudio apps route through
    # PipeWire transparently without needing to be recompiled
    pipewire-alsa pipewire-jack pipewire-pulse

    qt5-wayland           # Qt5 Wayland platform plugin for native rendering
    qt6-wayland           # Qt6 Wayland platform plugin for native rendering
    swww                  # smooth animated wallpaper daemon for wlroots
    ttf-jetbrains-mono    # monospace coding font used in terminals/bar
    wireplumber           # PipeWire session and policy manager

    xdg-desktop-portal-hyprland # Hyprland XDG portal (screen share, file pick)
    xdg-utils                   # xdg-open and MIME handling utilities
    # Note: qt6ct is NOT included in hyprlua (differs from hyprland.sh)

    xorg-server           # X server for XWayland (legacy X11 apps)
    xorg-xinit            # startx / xinitrc support for XWayland
    papirus-icon-theme    # icon theme used system-wide and by udiskie

    cool-retro-term       # retro CRT-style terminal emulator
    qalculate-gtk         # full-featured GTK calculator with unit conversion
    iwd                   # Intel Wireless Daemon (lighter Wi-Fi stack than wpa_supplicant)
    dbus                  # D-Bus inter-process communication daemon

    thunar                # lightweight GTK file manager
    tumbler               # D-Bus thumbnail service for Thunar
    thunar-archive-plugin # archive (zip/tar) right-click integration
    thunar-shares-plugin  # Samba share management in Thunar
    thunar-volman         # automatic volume/device mounting in Thunar

    hyprpicker            # colour picker outputting hex/rgb/hsl values
    pcmanfm-qt            # Qt file manager (kept as fallback / alternative)
    udisks2               # D-Bus daemon for querying and managing storage devices
    kew                   # terminal-based music player

    hyprpolkitagent         # Hyprland-native Polkit authentication agent
    pavucontrol             # PulseAudio/PipeWire GUI volume mixer
    playerctl               # MPRIS media player CLI controller
    wf-recorder             # screen recorder for wlroots-based compositors
    sound-theme-freedesktop # standard freedesktop sound event samples

    python-opencv         # OpenCV Python bindings; webcam presence-detection daemon
    v4l-utils             # Video4Linux2 tools for enumerating and configuring webcams
)
sudo pacman -Syu --noconfirm --needed -- "${HYPRLUA_PACKAGES[@]}"

# ---------------------------------------------------------------------------
# 3. Enable essential services
# ---------------------------------------------------------------------------
log "Enabling essential services..."

# NetworkManager: manages all network connections (wired, Wi-Fi, VPN).
enable_service NetworkManager.service

# Greeter: HyprLua uses LightDM with the cyberqueer GTK greeter. The lightdm
# module installs LightDM, deploys its themed config + skull background, disables
# the competing greeters (greetd from core.sh, ly, and the tty1 getty) and
# enables lightdm.service — so exactly one display manager owns the login screen.
# ly remains available as a standalone module (optional-Modules/apps/ly.sh) for
# anyone who prefers it.
bash "$(dirname "${BASH_SOURCE[0]}")/../optional-Modules/apps/lightdm.sh"

# udisks2: D-Bus block-device service required by udiskie for auto-mounting.
enable_service udisks2.service

# ---------------------------------------------------------------------------
# 4. Install AUR packages
# ---------------------------------------------------------------------------
log "Installing AUR packages..."

# Pin the stable Rust toolchain so EWW and AUR Rust packages compile cleanly.
rustup default stable

# yay flags:
#   --answerdiff None   — skip PKGBUILD diff display (non-interactive)
#   --answerclean All   — always clean build directories
#   --noconfirm         — suppress all confirmation prompts
#   --needed            — skip packages that are already up-to-date (added vs
#                         hyprland.sh to avoid redundant AUR rebuilds)
#
# Packages:
#   hyprland-workspaces — EWW workspace widget (reads Hyprland IPC)
#   vicinae-bin         — pre-built vicinae (vim-modal keybind layer)
#   bluetuith           — TUI Bluetooth manager (text-based device control)
#   wvkbd               — on-screen virtual keyboard for Wayland (tablet use)
#   iwmenu              — wofi/dmenu Wi-Fi picker driven by iwd
#   pinta               — accessible image editor (Paint.NET-like)
#   walker-bin          — fast application launcher (pre-built binary)
#   ulauncher           — extensible launcher with plugin support
#   bzmenu              — quick Bluetooth connect menu for the bar
#   udiskie             — auto-mounter with tray icon (built on udisks2)
#   wofi-calc           — inline calculator inside wofi
#   bri                 — brightness control helper for bar widgets
#   chamel              — colour-palette / theme switcher
#   libastal-*-git      — Astal GObject service libraries consumed by astal-menu
#                         (io, apps, network, bluetooth) via PyGObject
yay -Syu --answerdiff None --answerclean All --noconfirm --needed \
    hyprland-workspaces vicinae-bin bluetuith wvkbd iwmenu pinta \
    walker-bin ulauncher bzmenu udiskie \
    wofi-calc bri chamel \
    libastal-io-git libastal-apps-git libastal-network-git libastal-bluetooth-git
# hyprmoncfg if custom script no worky

# ---------------------------------------------------------------------------
# 5. EWW bar selection and compilation
# ---------------------------------------------------------------------------
# EWW (Elkowar's Wacky Widgets) powers the custom status bar.
# Three form-factor layouts ship in the Dotfiles:
#   eww/            — Notebook: includes battery percentage widget
#   eww-nobattery/  — Desktop PC: no battery widget
#   eww-touch/      — Tablet: larger touch targets + right-click emulation
log "Setting up EWW bar..."

# Remove any existing EWW config to avoid leftover widget definitions.
rm -rf ~/.config/eww

# Single-keystroke form-factor selection (no Enter required).
# Skip the prompt in unattended installs (answerfile mode) or when stdin is not
# a terminal — otherwise the read blocks forever during automated deployment.
# Default to the desktop/no-battery layout, the safe choice for VMs and PCs.
if [[ "${MARCHY_UNATTENDED:-0}" == "1" || ! -t 0 ]]; then
    doit="P"
    log "Unattended mode — installing desktop (no-battery) EWW bar."
else
    read -n1 -p "Install eww bar for PC, Notebook or Tablet [P/N/T]: " doit
    echo  # Newline after single-char read
fi

case $doit in
    # Notebook: battery-aware layout
    n|N) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww/ ~/.config/ ;;
    # Desktop PC: no battery widget
    p|P) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww-nobattery/ ~/.config/eww ;;
    # Tablet: touch layout + right-click emulation daemon
    t|T) cp -rf ~/Dotfiles/desktopenvs/hyprlua/eww-touch/ ~/.config/eww
         # evdev-right-click-emulation enables long-press → right-click on touch
         # screens; its systemd service must be started alongside the session.
         yay -S --noconfirm evdev-right-click-emulation
         enable_service evdev-rce.service; start_service evdev-rce.service ;;
    # Unrecognised key: leave ~/.config/eww absent; user must copy manually.
    *)   warn "No valid choice — skipping EWW copy. Run manually later." ;;
esac

log "Compiling EWW..."
# EWW is not packaged in the official repos; we compile from source.
# ~/install-tmp is the staging directory for source trees fetched during install.
mkdir -p ~/install-tmp
cd ~/install-tmp
git clone https://github.com/elkowar/eww
cd eww
# --release             → produce an optimised binary (noticeably faster UI)
# --no-default-features → exclude the X11 backend (we only target Wayland)
# --features=wayland    → enable the Wayland back-end explicitly
cargo build --release --no-default-features --features=wayland
chmod +x target/release/eww
# Install system-wide so autostart entries and scripts can invoke 'eww' directly.
sudo cp target/release/eww /usr/bin/
cd ~  # Return home so subsequent relative paths resolve correctly

# ---------------------------------------------------------------------------
# 6. Theme and icon setup
# ---------------------------------------------------------------------------
log "Installing themes and icons..."

# Install the cyberqueer GTK theme system-wide for GTK2/3/4 application styling.
sudo cp -r ~/Dotfiles/gtk-themes/cyberqueer /usr/share/themes

# Install the matching btop resource-monitor colour theme.
sudo cp ~/Dotfiles/desktopenvs/hyprlua/btop/themes/cyberqueer.theme /usr/share/btop/themes

# (The login greeter — LightDM + cyberqueer GTK greeter — is set up in step 3
# via the lightdm module, which also deploys the greeter theme and background.)

# Register kitty as the system terminal for xdg-terminal-exec so file managers
# and scripts that open "a terminal here" consistently launch kitty.
sudo ln -sf /usr/bin/kitty /usr/bin/xdg-terminal-exec

# Register ksshaskpass as the SSH passphrase GUI helper.
# SSH clients look for /usr/lib/ssh/ssh-askpass when they need a passphrase
# but have no controlling terminal available (e.g. git push from a bar widget).
sudo ln -sf /usr/bin/ksshaskpass /usr/lib/ssh/ssh-askpass

# Qt theming via qt-themes/cyberqueer is commented out (kept for reference);
# the Qt5 / Qt6 colour scheme is currently handled via qt6ct manual setup.
#bash ~/Dotfiles/qt-themes/cyberqueer/enable.sh

# Instruct GTK apps that prefer the system colour-scheme to use dark mode.
# This is particularly important under Hyprland where there is no GNOME
# settings daemon propagating the user's preference automatically.
# gsettings needs a session D-Bus (dconf) — absent in the installer chroot, where
# it would hang/fail — so only apply it when a user bus is reachable.
if have_user_bus; then
    gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark' || true
else
    skip "No session bus — set GTK dark mode after first login (gsettings)."
fi

# ---------------------------------------------------------------------------
# 7. Cursor setup
# ---------------------------------------------------------------------------
# Nordzy-cursors-lefthand is a Nord-palette left-handed cursor theme.
# Downloaded directly from GitHub Releases for a pinned version; the AUR
# build can lag behind upstream.
log "Installing cursor theme..."
mkdir -p ~/.icons
curl -fL -o ~/install-tmp/Nordzy-cursors-lefthand.tar.gz \
    https://github.com/guillaumeboehm/Nordzy-cursors/releases/download/v2.3.0/Nordzy-cursors-lefthand.tar.gz
# Extract into ~/.icons/ so both Hyprland (hyprcursor) and GTK apps can find it.
tar -zxf ~/install-tmp/Nordzy-cursors-lefthand.tar.gz -C ~/.icons/

# ---------------------------------------------------------------------------
# 8. Enable Bluetooth and wireless services
# ---------------------------------------------------------------------------
log "Enabling Bluetooth and wireless services..."

# bluez: core Bluetooth daemon; powers adapters and makes them available on boot
enable_service bluez
# bluetooth.service: handles pairing, profiles, and device reconnection
enable_service bluetooth.service
# iwd: Intel Wireless Daemon; the Wi-Fi back-end used by iwmenu in the bar
enable_service iwd.service
#systemctl --user enable --now hyprmoncfgd

# ---------------------------------------------------------------------------
# 9. Hyprland plugins (must be run inside a live Hyprland session)
# ---------------------------------------------------------------------------
# hyprpm links against the exact running compositor binary, so it cannot be
# invoked from the installer.  After first login, run:
#   hyprpm update
#   hyprpm add https://github.com/hyprwm/hyprland-plugins

# ---------------------------------------------------------------------------
# 10. Copy configs
# ---------------------------------------------------------------------------
log "Copying configs..."

# Deploy each config directory from the hyprlua Dotfiles source.
# The wipe-then-copy pattern ensures no stale files from older installs remain.
CONFIGS=(kitty mimeapps.list vicinae walker ulauncher hypr xfce4 wofi dunst alacritty astal-menu nwg-panel scripts btop gtk-3.0)
for cfg in "${CONFIGS[@]}"; do
    rm -rf ~/.config/"$cfg"
    cp -r ~/Dotfiles/desktopenvs/hyprlua/"$cfg" ~/.config/
done

# Vicinae loads NAMED custom themes from ~/.local/share/vicinae/themes/*.toml —
# NOT from ~/.config/vicinae/. The cyberqueer.toml copied above (into
# ~/.config/vicinae/) is therefore never found, so settings.json's
# theme.dark.name="cyberqueer" silently falls back to the stock dark theme.
# Deploy the theme into the location Vicinae actually scans so it resolves.
mkdir -p ~/.local/share/vicinae/themes
cp -f ~/Dotfiles/desktopenvs/hyprlua/vicinae/cyberqueer.toml \
      ~/.local/share/vicinae/themes/cyberqueer.toml

# In hyprlua, device-specific overrides (monitors, keybinds, autostart, etc.)
# live inside ~/.config/hypr/usr/ as Lua modules loaded by hyprland.lua via
# require("usr.*").  The usr/ directory is already bundled inside the hypr/
# directory copied above, so no separate step is needed here.
# After install, customise ~/.config/hypr/usr/ per device as needed.

# Shared colour palette used by EWW bar, dunst, and scripts.
cp ~/Dotfiles/colors.conf ~/.config/colors.conf

# ---------------------------------------------------------------------------
# 11. Wallpaper and resources
# ---------------------------------------------------------------------------
log "Copying wallpaper and resources..."
mkdir -p ~/Pictures

# Firefox logo SVG for the dock/launcher shortcut icon.
cp ~/Dotfiles/resources/fflogo.svg ~/Pictures/fflogo.svg

# Download the personalised wallpaper from the owner's Nextcloud instance.
# ?v=15 is a cache-buster on the Nextcloud theming background API endpoint.
curl -fL "https://cloud.abdelbaki.eu/apps/theming/image/background?v=15" -o ~/Pictures/background.jpg

# ---------------------------------------------------------------------------
# 12. Python venv for scripts
# ---------------------------------------------------------------------------
# Helper scripts (weather widget, speed test, unit converter, timer, etc.) need
# these third-party Python libraries.  An isolated venv keeps them separate from
# system Python packages managed by pacman to avoid conflicts.
log "Setting up Python venv for scripts..."
python -m venv ~/.config/python-script
~/.config/python-script/bin/pip install \
    speedtest-cli   `# Internet speed test (EWW bar widget)` \
    requests        `# HTTP client for API-driven widgets` \
    pint            `# Unit conversion library` \
    simpleeval      `# Safe maths expression evaluator (wofi-calc)` \
    parsedatetime   `# Natural-language date/time parser for timer scripts`

# ---------------------------------------------------------------------------
# 13. Udiskie icon fix
# ---------------------------------------------------------------------------
# udiskie expects freedesktop icon names (udiskie-checkbox-checked, etc.) that
# Papirus-Dark does not ship under those exact names.  We symlink Papirus-Dark's
# existing checkbox SVGs into the hicolor fallback theme under the names udiskie
# expects, then rebuild the cache so GTK picks them up immediately.
log "Applying Udiskie icon fix..."
PAPIRUS_DIR="/usr/share/icons/Papirus-Dark/status"
HICOLOR_DIR="/usr/share/icons/hicolor/scalable/status"
if [ -d "$PAPIRUS_DIR" ]; then
    sudo ln -sf "$PAPIRUS_DIR/checkbox-checked.svg"   "$HICOLOR_DIR/udiskie-checkbox-checked.svg"
    sudo ln -sf "$PAPIRUS_DIR/checkbox-unchecked.svg" "$HICOLOR_DIR/udiskie-checkbox-unchecked.svg"
    # Rebuild the GTK icon cache so apps find the new symlinks without restart.
    sudo gtk-update-icon-cache -f -t /usr/share/icons/hicolor
else
    warn "Papirus-Dark not found — skipping udiskie icon fix."
fi

# ---------------------------------------------------------------------------
# 14. Enable udiskie
# ---------------------------------------------------------------------------
# udiskie auto-mounts removable drives and shows a tray icon for each volume.
# Enable the systemd unit for future boots and start it immediately so USB
# devices inserted during this session are handled right away.
log "Enabling udiskie service..."
enable_service udiskie.service
start_service udiskie.service

# ---------------------------------------------------------------------------
# 15. Install config updater and theme script
# ---------------------------------------------------------------------------
# config-updater selectively re-syncs config files from the Dotfiles repo
# without re-running the full installer.  updater.conf lists which files are
# managed; update-configs.sh performs the sync.
#
# Symlinks are used (not copies) so that pulling the latest Dotfiles with
# 'git pull' takes effect immediately on the next sync run.
log "Installing config updater and theme script..."
mkdir -p ~/.config/config-updater
ln -sf ~/Dotfiles/desktopenvs/hyprlua/config-updater/updater.conf ~/.config/config-updater/updater.conf
ln -sf ~/Dotfiles/desktopenvs/hyprlua/config-updater/update-configs.sh ~/update-configs.sh

# apply-theme.sh applies the cyberqueer palette across all running apps
# (reloads dunst, refreshes EWW variables, sets GTK/Qt themes).
# Copied rather than symlinked so it is available even when ~/Dotfiles is absent.
cp ~/Dotfiles/apply-theme.sh ~/apply-theme.sh
chmod +x ~/apply-theme.sh

log "HyprLua installation complete. Reboot to start."
