# shellcheck shell=bash
# functions.sh — shell functions, stow-friendly
# Repo path: bashrc/.config/bash/functions.sh -> stows to ~/.config/bash/functions.sh
# Sourced from ~/.bashrc via: source_shell_file "${XDG_CONFIG_HOME:-$HOME/.config}/bash/functions.sh"

[[ $- != *i* ]] && return 0

# Fallback if sourced standalone (normally provided by .bashrc)
declare -F has_tool >/dev/null 2>&1 || has_tool() { command -v "$1" >/dev/null 2>&1; }

#######################################################
# GIT SHORTCUTS
#######################################################
# omz-style names. `gc` joins all words into one message; `gca` amends the
# last commit with staged changes, reusing its message (no editor opens).
gst() { git status "$@"; }
ga() {
    if [ $# -eq 0 ]; then
        git add .
    else
        git add "$@"
    fi
}
gc() { git commit -m "$*"; }
gca() { git commit --amend --no-edit "$@"; }
gp() { git push "$@"; }
gl() { git pull "$@"; }

# Extracts any archive(s) (if unp isn't installed)
extract() {
    local archive
    for archive in "$@"; do
        if [ -f "$archive" ]; then
            case "$archive" in
                *.tar.bz2 | *.tbz2) tar xvjf "$archive" ;;
                *.tar.gz | *.tgz) tar xvzf "$archive" ;;
                *.tar.xz) tar xvJf "$archive" ;;
                *.bz2) bunzip2 "$archive" ;;
                *.rar)
                    if has_tool unrar; then
                        unrar x "$archive"
                    else
                        echo "unrar not installed"
                    fi
                    ;;
                *.gz) gunzip "$archive" ;;
                *.tar) tar xvf "$archive" ;;
                *.zip) unzip "$archive" ;;
                *.Z) uncompress "$archive" ;;
                *.7z)
                    if has_tool 7z; then
                        7z x "$archive"
                    else
                        echo "7z not installed"
                    fi
                    ;;
                *.xz) unxz "$archive" ;;
                *) echo "don't know how to extract '$archive'..." ;;
            esac
        else
            echo "'$archive' is not a valid file!" >&2
        fi
    done
}

# Searches for text in all files in the current folder
ftext() {
    if has_tool rg; then
        rg -i "$1" .
    else
        grep -iIHrn --color=always "$1" . 2>/dev/null | less -r
    fi
}

# Show how a command resolves (alias/function/builtin/file)
checkcommand() {
    type -a "$@" 2>/dev/null || echo "Command not found: $*"
}

# Count files, links, and directories (recursively) in the current folder
countfiles() {
    local t
    for t in files links directories; do
        echo "$(find . -type "${t:0:1}" | wc -l)" "$t"
    done 2>/dev/null
}

# Copy and go to the directory
cpg() {
    local src="$1" dest="$2"
    if [ -d "$dest" ]; then
        cp -r "$src" "$dest" || return
        cd "$dest" || return
    else
        cp -r "$src" "$dest"
    fi
}

# Move and go to the directory
mvg() {
    local src="$1" dest="$2"
    if [ -d "$dest" ]; then
        mv "$src" "$dest" || return
        cd "$dest" || return
    else
        mv "$src" "$dest"
    fi
}

# Create and go to the directory
mkdirg() {
    local dir_name="$1"
    mkdir -p "$dir_name" || return
    cd "$dir_name" || return
}

# Goes up a specified number of directories (i.e. up 4)
up() {
    local limit=${1:-1}
    local target_path=""
    for ((i = 0; i < limit; i++)); do
        target_path="../${target_path}"
    done
    cd "${target_path}" || return
}

# Repo greeting: show onefetch banner when entering a different git repository
last_repository=""
_get_git_root() {
    git rev-parse --show-toplevel 2>/dev/null || true
}
_show_repo_greeting_if_needed() {
    local current_repository
    current_repository="$(_get_git_root)"
    if [ -n "$current_repository" ] && [ "$current_repository" != "$last_repository" ]; then
        onefetch -d churn --no-merges --nerd-fonts
    fi
    last_repository="$current_repository"
}
_maybe_repo_greeting() {
    has_tool onefetch || return 0
    _show_repo_greeting_if_needed
}

# Automatically do an ls after each cd, z, or zoxide
cd() {
    local target_dir="$1"
    if [ -n "$target_dir" ]; then
        builtin cd "$target_dir" && (
            set --
            ls
        ) || return
    else
        builtin cd ~ && (
            set --
            ls
        ) || return
    fi
    _maybe_repo_greeting
}

# Show the current distribution
distribution() {
    if [ -r /etc/os-release ]; then
        source /etc/os-release
        case "${ID:-}" in
            fedora | rhel | centos | rocky | almalinux) echo "redhat" ;;
            sles | opensuse*) echo "suse" ;;
            ubuntu | debian) echo "debian" ;;
            gentoo) echo "gentoo" ;;
            arch | manjaro | endeavouros) echo "arch" ;;
            slackware) echo "slackware" ;;
            alpine) echo "alpine" ;;
            *)
                case "${ID_LIKE:-}" in
                    *fedora* | *rhel* | *centos*) echo "redhat" ;;
                    *suse*) echo "suse" ;;
                    *ubuntu* | *debian*) echo "debian" ;;
                    *gentoo*) echo "gentoo" ;;
                    *arch*) echo "arch" ;;
                    *) echo "unknown" ;;
                esac
                ;;
        esac
    elif [ -f /etc/redhat-release ]; then
        echo "redhat"
    elif [ -f /etc/debian_version ]; then
        echo "debian"
    elif [ -f /etc/arch-release ]; then
        echo "arch"
    else
        echo "unknown"
    fi
}

# Show the current version of the operating system
ver() {
    local dtype
    dtype=$(distribution)

    case "$dtype" in
        "redhat")
            if [ -r /etc/redhat-release ]; then
                cat /etc/redhat-release
            else
                cat /etc/os-release
            fi
            ;;
        "suse")
            if [ -r /etc/os-release ]; then
                cat /etc/os-release
            elif [ -r /etc/SuSE-release ]; then
                cat /etc/SuSE-release
            else
                echo "Unknown distribution" >&2
            fi
            ;;
        "debian")
            if has_tool lsb_release; then
                lsb_release -a
            else
                cat /etc/os-release
            fi
            ;;
        "gentoo")
            if [ -r /etc/gentoo-release ]; then
                cat /etc/gentoo-release
            else
                cat /etc/os-release
            fi
            ;;
        "arch")
            cat /etc/os-release
            ;;
        "alpine")
            if [ -r /etc/alpine-release ]; then
                cat /etc/alpine-release
            else
                cat /etc/os-release
            fi
            ;;
        *)
            if [ -r /etc/os-release ]; then
                cat /etc/os-release
            else
                echo "Unknown distribution" >&2
            fi
            ;;
    esac
    echo -e "\nKernel: $(uname -sr)"
}

# Automatically install the needed support files for this .bashrc file
install_bashrc_support() {
    local dtype
    dtype=$(distribution)

    case "$dtype" in
        "redhat")
            if has_tool dnf; then
                sudo dnf install -y --skip-broken --refresh --skip-unavailable tree zoxide fzf bash-completion fastfetch bat ripgrep alacritty
            else
                sudo yum install -y -q tree zoxide fzf bash-completion fastfetch eza bat ripgrep alacritty
            fi
            ;;
        "suse")
            sudo zypper install -n --auto-agree-with-licenses tree zoxide fzf bash-completion fastfetch eza bat ripgrep alacritty
            ;;
        "debian")
            sudo apt-get update
            sudo apt-get install tree zoxide fzf bash-completion eza bat ripgrep alacritty
            local FASTFETCH_URL
            FASTFETCH_URL=$(curl -s https://api.github.com/repos/fastfetch-cli/fastfetch/releases/latest | grep "browser_download_url.*linux-amd64.deb" | cut -d '"' -f 4)
            if [ -n "$FASTFETCH_URL" ]; then
                curl -sL "$FASTFETCH_URL" -o /tmp/fastfetch_latest_amd64.deb
                sudo apt-get install /tmp/fastfetch_latest_amd64.deb
                rm /tmp/fastfetch_latest_amd64.deb
            else
                echo "Warning: Could not find fastfetch .deb URL." >&2
            fi
            ;;
        "arch")
            if has_tool yay; then
                yay -S --noconfirm --needed zoxide fzf bash-completion fastfetch starship eza bat ripgrep ttf-firacode-nerd trash-cli fd yazi tlrc-bin alacritty
            elif has_tool pacman; then
                sudo pacman -S --noconfirm --needed zoxide fzf bash-completion fastfetch starship eza bat ripgrep ttf-firacode-nerd trash-cli fd yazi alacritty
            else
                echo "Neither yay nor pacman found. Cannot install." >&2
            fi
            ;;
        "slackware")
            echo "No install support for Slackware" >&2
            ;;
        *)
            echo "Unknown distribution. Cannot install." >&2
            ;;
    esac
}

install_i3_support() {
    local dtype
    dtype=$(distribution)

    case "$dtype" in
        "debian" | "suse")
            echo "i3 support installation not yet implemented for $dtype-based systems." >&2
            ;;
        "redhat")
            if has_tool dnf; then
                sudo dnf install -y --skip-broken --refresh --skip-unavailable tree zoxide fzf bash-completion fastfetch bat ripgrep alacritty
            else
                sudo yum install -y -q tree zoxide fzf bash-completion fastfetch eza bat ripgrep alacritty
            fi
            ;;
        "arch")
            if has_tool yay; then
                yay -S --needed --noconfirm picom feh i3-auto-tiling rofi flameshot xclip alacritty
            elif has_tool pacman; then
                sudo pacman -S --needed --noconfirm picom feh rofi flameshot xclip alacritty
                echo "⚠️  'i3-auto-tiling' is not in official repos; skipping." >&2
            else
                echo "❌ Neither yay nor pacman found. Cannot install." >&2
            fi
            ;;
        "slackware")
            echo "Slackware is not supported for automated i3 setup." >&2
            ;;
        *)
            echo "Unknown distribution: $dtype. Cannot install i3 support." >&2
            ;;
    esac
}

# IP address lookup
whatsmyip() {
    echo -n "Internal IP: "
    if has_tool ip; then
        ip -4 addr show scope global | awk '/inet / {print $2}' | cut -d/ -f1 | head -n 1
    elif has_tool ifconfig; then
        ifconfig | awk '/inet / && $2 != "127.0.0.1" {print $2}' | head -n 1
    else
        echo "N/A"
    fi
    echo -n "External IPv4: "
    curl -s --connect-timeout 5 https://api.ipify.org || echo "N/A"
    echo -n -e "\nExternal IPv6: "
    curl -s --connect-timeout 5 https://api6.ipify.org || echo "N/A"
}
alias myip="whatsmyip"

# YAZI (with CWD sync support)
if has_tool yazi; then
    function y() {
        local tmp cwd
        tmp="$(mktemp -t "yazi-cwd.XXXXXX")"
        yazi "$@" --cwd-file="$tmp"
        IFS= read -r -d '' cwd <"$tmp"
        if [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
            builtin cd -- "$cwd" || :
        fi
        rm -f -- "$tmp"
    }
fi
