# shellcheck shell=bash

# If not running interactively, don't do anything.
[[ $- != *i* ]] && return

# Color definitions
_WHITE='\033[1;37m'          # White
_NC='\033[0m'                # No color

_RED='\033[0;31m'            # Red
_GREEN='\033[01;32m'         # Bright Green
_YELLOW='\033[0;33m'         # Yellow
_BLUE='\033[1;34m'           # Bright Blue
_BRIGHT_GREEN='\033[1;32m'   # Bright Green (for positive)
_BRIGHT_RED='\033[1;31m'     # Bright Red (for negative)
_BRIGHT_WHITE='\033[1;37m'   # Bright White
_DIM_RED='\033[91m'          # Bright Red (for TODO files)

export SHELL_CONFIG="${SHELL_CONFIG:+${SHELL_CONFIG}:}.bashrc"
#
# ~/.bashrc
#

function show_date() {
    local dotfile selected_adjective adjective classification
    local day_of_week day_of_month month_name year day_suffix text_color full_date
    local -a adjectives

    # Define the dot file to store the selected adjective
    dotfile="$HOME/.adjective_of_the_day"

    # Check if the dot file exists and was modified since yesterday
    if [[ -f "$dotfile" && $(date -d "$(stat -c %y "$dotfile")" +%s) -ge $(date -d 'yesterday' +%s) ]]; then
        # If the dot file exists and was modified since yesterday
        # read the stored adjective from the file
        selected_adjective=$(cat "$dotfile")
    else
        # Define an array of adjectives with classifications
        adjectives=(
            "beautiful:positive"
            "engaging:positive"
            "majestic:positive"
            "distinguished:positive"
            "venerable:positive"
            "formal:positive"
            "elegant:positive"
            "serene:positive"
            "graceful:positive"
            "regal:positive"
            "noble:positive"
            
            "miserable:negative"
            "worthless:negative"
            "depressing:negative"
            "soulless:negative"
            "desolate:negative"
            "archaic:negative"
            "grim:negative"
            "dreadful:negative"
            "forlorn:negative"
            "wretched:negative"
            
            "neutral:neutral"
            "ordinary:neutral"
            "common:neutral"
            "antique:neutral"
            "ceremonial:neutral"
            "timeless:neutral"
            "classic:neutral"
            "historic:neutral"
            "ancient:neutral"
        )

        # Select a random adjective from the array
        selected_adjective="${adjectives[$RANDOM % ${#adjectives[@]}]}"

        # Store the selected adjective in the dot file
        echo "$selected_adjective" > "$dotfile"
    fi

    # Split the selected adjective into the adjective and classification parts
    IFS=':' read -r adjective classification <<< "$selected_adjective"

    # Get the current day of the week, day of the month, and year
    day_of_week=$(date "+%A")
    day_of_month=$(date "+%d")
    month_name=$(date "+%B")
    year=$(date "+%Y")

    # Determine the day suffix (th, nd, rd)
    case "$day_of_month" in
        1[0-9]) day_suffix="th";;
        *1) day_suffix="st";;
        *2) day_suffix="nd";;
        *3) day_suffix="rd";;
        *) day_suffix="th";;
    esac

    # Determine the color based on the classification
    case "$classification" in
        "positive") text_color="$_BRIGHT_GREEN";;
        "negative") text_color="$_BRIGHT_RED";;
        *) text_color="";;
    esac

    # Create the full date format with colored parts and the selected adjective
    full_date="Pray, be informed, on this ${text_color}${adjective}${_NC} day,\n${_BLUE}${day_of_week}${_NC} the ${_BLUE}${day_of_month}${day_suffix}${_NC} day of ${_BLUE}${month_name}${_NC}, in the year of our Lord ${_BLUE}${year}${_NC}!"

    # Print the full date
    echo -e "$full_date"
    echo ""
}


# ============================================================================
# SHELL CONFIGURATION
# ============================================================================

export HISTCONTROL=ignoreboth:erasedups
export HISTFILE="$HOME/.histfile"
export HISTSIZE=10000
export HISTFILESIZE=10000
shopt -s histappend checkwinsize

# Disable terminal flow-control keys only when stdin is a terminal.
[[ -t 0 ]] && stty -ixon

# Optimized divider function - simple timestamp without coloring
function draw_prompt_divider() {
  local timestamp prefix_length line_length i
  printf -v timestamp '%(%H:%M:%S)T' -1  # Faster than $(date)
  local prefix="$timestamp ├"
  prefix_length=${#prefix}
  line_length=$(( ${COLUMNS:-80} - prefix_length ))
  
  # Print timestamp, junction, then fill with box-drawing characters
  printf '%s' "$prefix"
  for ((i=0; i<line_length; i++)); do printf '─'; done
  echo
}

# Cache static values that don't change during session
_CACHED_USER_HOST="$USER@$HOSTNAME"
_CACHED_USER_HOST_LENGTH=${#_CACHED_USER_HOST}

# Optimized git alignment calculation
function calculate_git_alignment() {
  # Only calculate if git status exists
  [[ -z "$GITSTATUS_PROMPT" ]] && { GIT_ALIGNMENT_PADDING=""; return; }
  
  # Fast branch name extraction - use sed for reliable escape sequence removal
  local cleaned
  cleaned=$(echo "$GITSTATUS_PROMPT" | sed -e 's/\x01//g' -e 's/\x02//g' -e 's/\x1b\[[0-9;]*m//g')
  local branch_name="${cleaned%% *}"  # Get first word (branch)
  
  # Calculate padding (cache the static hostname length)
  local needed_padding=$((_CACHED_USER_HOST_LENGTH - ${#branch_name}))
  [[ $needed_padding -lt 8 ]] && needed_padding=8
  
  # Use printf once to generate padding
  printf -v GIT_ALIGNMENT_PADDING '%*s' $needed_padding ''
}

# Persist each command promptly so a crashed terminal loses as little history
# as possible. Bash preserves the user's command status while running
# PROMPT_COMMAND, so this does not alter the prompt's error indicator or `$?`.
function append_new_history() {
	history -a
}

# Load custom gitstatus configuration
[ -f "$HOME/.config/bash/gitstatus-custom.sh" ] && . "$HOME/.config/bash/gitstatus-custom.sh"

# Set up prompt command to save history, draw the divider, update git status,
# and calculate alignment.
PROMPT_COMMAND="append_new_history; draw_prompt_divider; my_gitstatus_prompt_update; calculate_git_alignment"

# Custom command_not_found_handle function to show errors in red
command_not_found_handle() {
    echo -e "\033[01;31mbash: $1: command not found\033[00m" >&2
    return 127
}
_error_block='██████'
# Set PS1 with user@host, directory, git status, and prompt ($ color works!)
PS1='\[\033[01;32m\]\u@\h\[\033[00m\] \[\033[1;34m\]\w\[\033[00m\]\n${GITSTATUS_PROMPT:+$GIT_ALIGNMENT_PADDING$GITSTATUS_PROMPT\n}$([ "$?" -eq 0 ] && echo "" || echo "\[\033[01;31m\]$_error_block\[\033[00m\] ")\$ \[\e]0;\u@\h: \w\a\]'

# If there are multiple matches for completion, Tab should cycle through them
bind TAB:menu-complete
# Display a list of the matching files
bind "set show-all-if-ambiguous on"
# Perform partial (common) completion on the first Tab press, only start
# cycling full results on the second Tab press (from bash version 5)
bind "set menu-complete-display-prefix on"

show_date

[ -r "$HOME/.config/profile/aliases.sh" ] && . "$HOME/.config/profile/aliases.sh"

export NVM_DIR="$HOME/.nvm"
if [[ -s "$NVM_DIR/nvm.sh" ]]; then
	\. "$NVM_DIR/nvm.sh"
	nvm use default >/dev/null
	[[ -s "$NVM_DIR/bash_completion" ]] && \. "$NVM_DIR/bash_completion"
fi

# https://github.com/skywind3000/z.lua
if command -v lua ; then
	eval "$(lua "$HOME/.z.lua/z.lua" --init bash enhanced once echo)"
fi > /dev/null

_mem_available=$(awk '/MemAvailable/ { printf "%.1f \n", $2/1024/1024 }' /proc/meminfo)
_package_status_cache="${XDG_CACHE_HOME:-$HOME/.cache}/package-status/status"
_package_status_attempt="${XDG_CACHE_HOME:-$HOME/.cache}/package-status/last-attempt"
_package_status_max_age=3600
_package_status_retry_delay=300
_package_status_version=""
_package_status_checked_at=""
_package_status_pacman_log_signature=""
_updates_available="0"
_orphans_available="0"

if [ -r "$_package_status_cache" ]; then
	while IFS='=' read -r _package_status_key _package_status_value; do
		case "$_package_status_key" in
			version) _package_status_version="$_package_status_value" ;;
			updates) _updates_available="$_package_status_value" ;;
			orphans) _orphans_available="$_package_status_value" ;;
			checked_at) _package_status_checked_at="$_package_status_value" ;;
			pacman_log_signature) _package_status_pacman_log_signature="$_package_status_value" ;;
		esac
	done < "$_package_status_cache"
fi

_package_status_now=$(date +%s)
_package_status_current_pacman_log_signature=$(stat -c '%Y:%s:%i' /var/log/pacman.log 2>/dev/null || echo '0:0:0')

if ! [[ "$_package_status_version" == "1" \
	&& "$_updates_available" =~ ^[0-9]+$ \
	&& "$_orphans_available" =~ ^[0-9]+$ \
	&& "$_package_status_checked_at" =~ ^[0-9]+$ \
	&& "$_package_status_pacman_log_signature" =~ ^[0-9]+:[0-9]+:[0-9]+$ \
	&& $_package_status_now -ge $_package_status_checked_at \
	&& $((_package_status_now - _package_status_checked_at)) -le $_package_status_max_age \
	&& "$_package_status_pacman_log_signature" == "$_package_status_current_pacman_log_signature" ]]; then
	_updates_available="0"
	_orphans_available="0"

	_package_status_attempt_time=$(stat -c %Y "$_package_status_attempt" 2>/dev/null || echo 0)
	if ! [[ "$_package_status_attempt_time" =~ ^[0-9]+$ \
		&& $_package_status_now -ge $_package_status_attempt_time \
		&& $((_package_status_now - _package_status_attempt_time)) -lt $_package_status_retry_delay ]]; then
		systemctl --user start --no-block package-status-refresh.service >/dev/null 2>&1 || true
	fi
fi

unset _package_status_cache _package_status_attempt _package_status_max_age
unset _package_status_retry_delay _package_status_attempt_time _package_status_version
unset _package_status_checked_at _package_status_pacman_log_signature
unset _package_status_now _package_status_current_pacman_log_signature
unset _package_status_key _package_status_value

echo "Remember commands:"
printf '%b' "$_WHITE"
_command_reminder
printf '%b\n' "$_NC"
echo ""

if [ ${_mem_available%.*} -lt 5 ] ; then
	echo -ne "Memory available:   ${_YELLOW}"
	[ ${_mem_available%.*} -lt 3 ] && echo -ne "${_RED}"
	echo -n "${_mem_available}"
	echo -e "GB${_NC}"
fi

if [ $_updates_available -gt 0 ] ; then
    update_color="$_BRIGHT_WHITE" # default white
    if [ $_updates_available -gt 29 ] ; then
        update_color="$_RED" # red
    elif [ $_updates_available -gt 15 ] ; then
        update_color="$_YELLOW" # yellow
    fi

    echo -ne "Updates available: ${update_color}${_updates_available}${_NC}"
    echo -ne " [ update with: ${update_color}update${_NC} ]"
    echo ""
fi

if [ $_orphans_available -gt 0 ] ; then
    echo -ne "Orphaned packages: $_BRIGHT_WHITE"

    orphan_color="$_BRIGHT_WHITE"
    if [ $_orphans_available -gt 9 ] ; then
        orphan_color="$_RED"
    elif [ $_orphans_available -gt 4 ] ; then
        orphan_color="$_YELLOW"
    fi

    echo -ne "${orphan_color}${_orphans_available}${_NC}"
    echo -ne " [ remove with: ${orphan_color}sudo pacman -Rns \$(pacman -Qdtq)${_NC} ]"
    echo ""
fi


echo ""
echo -e "Remember \"${_BLUE}TODO.md${_NC}\" (${_BLUE}et${_NC}) and \"${_BLUE}autonote.md${_NC}\" (${_BLUE}ea${_NC}) files have content automatically displayed."
echo ""

[ -r "$HOME/.config/bash/cheat.bash" ] && . "$HOME/.config/bash/cheat.bash"

#openai codex completion
if command -v codex >/dev/null 2>&1; then
	eval "$(codex completion bash)"
fi

# Function to check for TODO.md and echo its contents
function check_todo() {
	if [ -f "TODO.md" ]; then
		echo
		echo -e "${_DIM_RED}TODO.md${_NC}"
		echo "---------------------------"
		if command -v mdcat >/dev/null 2>&1; then mdcat TODO.md; else cat TODO.md; fi
		echo "---------------------------"
		echo
	fi
}
# Function to check for .autonote.md and echo its contents
function check_autonote() {
	if [ -f ".autonote.md" ]; then
		echo
		echo -e "${_DIM_RED}autonote.md${_NC}"
		echo "---------------------------"
		if command -v mdcat >/dev/null 2>&1; then mdcat .autonote.md; else cat .autonote.md; fi
		echo "---------------------------"
		echo
	fi
}
# Hook to execute check_todo, check_autonote when changing directories
cd() {
    builtin cd "$@" || return
    check_todo
	check_autonote
	return 0
}

# opencode
case ":$PATH:" in
	*":$HOME/.opencode/bin:"*) ;;
	*) export PATH="$HOME/.opencode/bin:$PATH" ;;
esac

#pyenv
export PYENV_ROOT="$HOME/.pyenv"
case ":$PATH:" in
	*":$PYENV_ROOT/bin:"*) ;;
	*) export PATH="$PYENV_ROOT/bin:$PATH" ;;
esac
if [[ -z ${PYENV_SHELL:-} ]] && command -v pyenv >/dev/null 2>&1; then
	eval "$(pyenv init -)"
fi
