# For interactive shells
[[ -n "$ZSH_PROFILE" ]] && {
  zmodload zsh/datetime
  zshrc_start_time=$EPOCHREALTIME
  zmodload zsh/zprof
}
HISTFILE=~/.zhistory
HISTSIZE=10000
SAVEHIST=10000
setopt \
  ALWAYS_TO_END \
  APPEND_HISTORY \
  AUTO_CD \
  AUTO_LIST \
  AUTO_MENU \
  AUTO_PARAM_SLASH \
  AUTO_PUSHD \
  BANG_HIST \
  C_BASES \
  COMPLETE_IN_WORD \
  EXTENDED_GLOB \
  EXTENDED_HISTORY \
  HIST_EXPIRE_DUPS_FIRST \
  HIST_FIND_NO_DUPS \
  HIST_IGNORE_DUPS \
  HIST_IGNORE_SPACE \
  HIST_LEX_WORDS \
  HIST_SAVE_NO_DUPS \
  HIST_VERIFY \
  INTERACTIVE_COMMENTS \
  LONG_LIST_JOBS \
  MULTIOS \
  NO_CLOBBER \
  NO_HUP \
  NOMATCH \
  NOTIFY \
  PUSHD_IGNORE_DUPS \
  PUSHD_SILENT \
  PUSHD_TO_HOME \
  RC_QUOTES \
  SHARE_HISTORY
unsetopt \
  BEEP \
  CDABLE_VARS \
  HIST_BEEP \
  LIST_BEEP \
  FLOW_CONTROL \
  MAIL_WARNING \
  HUP \
  BG_NICE \
  CHECK_JOBS
# vi keybindings
bindkey -v

# Allow core files
ulimit -c unlimited

DIRSTACKSIZE=16

export OS="$(uname 2>/dev/null || echo "Unknown")"

# Set terminal title
case $TERM in
  # Only set the title for terminals that are likely to support it
  xterm*|screen*)
    # add-zsh-hook is a zsh utility for managing hooks
    autoload -U add-zsh-hook

    # Variable to hold the manual title, initialized to empty
    MANUAL_TERMINAL_TITLE=""

    # Manually set the terminal title. Clears the title if no argument is given.
    set_title() {
      MANUAL_TERMINAL_TITLE="${1:-}" # Assign argument or empty string
      # If the argument is empty, restore the automatic title.
      if [ -z "${MANUAL_TERMINAL_TITLE}" ] ; then
        _term_precmd
        return
      fi
      # Otherwise, set the manual title.
      if test -n "${TMUX}" ; then
        print -Pn "\e]2;${MANUAL_TERMINAL_TITLE}\e\\"
      else
        print -Pn "\e]0;${MANUAL_TERMINAL_TITLE}\a"
      fi
    }

    # precmd hook runs before each prompt
    _term_precmd() {
      # If a manual title is set, do nothing.
      if test -n "${MANUAL_TERMINAL_TITLE}" ; then
        return
      fi
      # emulate zsh to ensure consistent behavior
      emulate -L zsh
      # If we are in tmux, we want to set the window title
      if test -n "${TMUX}" ; then
        # Set tmux window title to a truncated path
        print -Pn "\e]2;%16<..<%~\e\\"
      else
        # this will also work in tmux but is not what we want
        # Set terminal title to user@host: path
        print -Pn "\e]0;%n@%m: %~\a"
      fi
    }
    # preexec hook runs before each command
    _term_preexec() {
      # If a manual title is set, do nothing.
      if test -n "${MANUAL_TERMINAL_TITLE}" ; then
        return
      fi
      # emulate zsh to ensure consistent behavior
      emulate -L zsh
      # Set local options to avoid affecting the rest of the shell
      setopt LOCAL_OPTIONS
      setopt EXTENDED_GLOB
      # extract the first word of the command that is not a match for the
      # pattern
      # (w) = match word
      # (r) = subscript value, not index
      # This extracts the command, ignoring environment variables and common wrappers
      local cmd=${1[(wr)^(*=*|sudo|ssh|mosh|-*)]:gs/%/%%}
      # If we are in tmux, we want to set the window title
      if test -n "${TMUX}" ; then
        # Set the tmux window title to the command being run
        print -Pn "\e]2;${cmd}\e\\"
      else
        # this will also work in tmux but is not what we want
        # Set the terminal title to include the command being run
        print -Pn "\e]0;%n@%m: %~ ($cmd)\a"
      fi
    }
    # Add the hooks to zsh
    add-zsh-hook precmd _term_precmd
    add-zsh-hook preexec _term_preexec
    ;;
esac

autoload -U colors && colors
PS1="%{$fg[black]%}[%{$fg[yellow]%}%h%{$fg[black]%}] %{%(!.$fg[red].$fg[green])%}%8>..>%n%>>%{$fg[white]%}@%{$fg[blue]%}%12>..>%m%>>%{$fg[white]%}:%{$fg[green]%}%32<...<%~%<<%{$fg[white]%}%#%{$reset_color%} "

zstyle ':completion:*:default' list-colors ${(s.:.)LS_COLORS}
zstyle ':completion::complete:*' use-cache on
zstyle ':completion::complete:*' cache-path "${ZDOTDIR:-$HOME}/.zcompcache"

# .profile is universal
emulate sh -c '. /etc/profile'
emulate sh -c '. ~/.profile'

# Additional Keybindings
bindkey '^[[A' history-search-backward
bindkey '^[[B' history-search-forward
# ctrl-arrow keys
bindkey '^[[1;5C' forward-word
bindkey '^[[1;5D' backward-word
bindkey '^P' up-history
bindkey '^N' down-history
bindkey '^?' backward-delete-char
bindkey '^h' backward-delete-char
# ok, a few emacs convenience bindings
bindkey '^w' backward-kill-word
bindkey '^r' history-incremental-search-backward
# delete really deletes
bindkey "^[[3~" delete-char

source_if_existing() {
  [[ -f "${1}" ]] && source "${1}"
}

source_first_existing() {
  while (($#)); do
    if test -e "${1}" ; then
      source "${1}"
      return
    fi
    shift
  done
  return 1
}

have_command() {
  command -v "${1}" &>/dev/null
}

if test -d ${HOME}/.local/bin ; then
  export PATH="${HOME}/.local/bin:${PATH}"
fi

# Source extras and aliases if interactive
if [[ $- == *i* ]] ; then
  source_if_existing $HOME/.aliases
  source_if_existing $HOME/.aliases.local
  # zsh-only-ism to avoid error if glob doesn't expand
  # specifically sets NULLGLOB for this one glob
  for file in $HOME/.zshrc.d/[a-zA-Z0-9]*.zsh(N) ; do
    source "$file"
  done
  # extra completions, prompt
  fpath=(~/.zshrc.completions ~/.zshrc.d/matir_prompt $fpath)
  # Homebrew on mac
  if test -x /opt/homebrew/bin/brew ; then
    eval $(/opt/homebrew/bin/brew shellenv)
  fi
  # Completion
  zstyle ':compinstall' filename "${HOME}/.zshrc"
  zstyle ':completion:*' users root ${USER}
  # Modules after fpath
  autoload -Uz compinit

  # Regenerate zcompdump if it's older than any file in fpath
  DUMPFILE="${ZDOTDIR:-$HOME}/.zcompdump"
  # Find the newest file across all fpath directories to detect edits/additions
  # (N.om[1]) = Null-glob, plain files only, sort by mtime, pick the first (newest)
  local newest_comp=(${^fpath}/*(N.om[1]))

  # If any completion file was modified, or dump doesn't exist, we might need to update.
  if [[ ! -f "$DUMPFILE" || ( -n "$newest_comp" && "$newest_comp" -nt "$DUMPFILE" ) ]]; then
    compinit -i -d "$DUMPFILE"
    # Asynchronously compile the dump file with an atomic rename
    { zcompile "$DUMPFILE.zwc.tmp" "$DUMPFILE" && mv -f "$DUMPFILE.zwc.tmp" "$DUMPFILE.zwc" } &!
  else
    compinit -C -i -d "$DUMPFILE"
  fi
  unset DUMPFILE newest_comp
  autoload -Uz promptinit && promptinit
  # Virtualenvwrapper
  source_first_existing \
    /usr/share/virtualenvwrapper/virtualenvwrapper_lazy.sh \
    /usr/bin/virtualenvwrapper_lazy.sh \
    /opt/homebrew/bin/virtualenvwrapper_lazy.sh
  if command ls --version >/dev/null 2>&1 ; then
    alias ls="$(whence -p ls) --color=auto"
  fi
  # Syntax highlighting and substring search
  source_first_existing \
    /usr/share/{,zsh/plugins/}zsh-syntax-highlighting/zsh-syntax-highlighting.zsh \
    /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
  if source_if_existing ${HOME}/.zshrc.d/_zsh-history-substring-search.zsh ; then
    bindkey '^[[A' history-substring-search-up
    bindkey '^[[B' history-substring-search-down
    bindkey -M vicmd 'k' history-substring-search-up
    bindkey -M vicmd 'j' history-substring-search-down
  fi
  # Suggestions
  if source_first_existing \
    /usr/share/{,zsh/plugins/}zsh-autosuggestions/zsh-autosuggestions.zsh ; then
    # Works well for solarized
    ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=10"
    # Strategy -- note that 'completion' is slow AF
    ZSH_AUTOSUGGEST_STRATEGY=(history)
  fi
  # History
  alias fullhist="history 1"
  alias longhist="history -1000"
  # direnv if present
  if command -v direnv >/dev/null 2>&1 ; then
    eval "$(direnv hook zsh)"
  fi
  test -e "${HOME}/.iterm2_shell_integration.zsh" && \
    source "${HOME}/.iterm2_shell_integration.zsh" || true
  # mise, if installed
  command -v mise >/dev/null 2>&1 && eval "$(mise activate zsh)"

  if test -z "${PAGER}" && command -v less >/dev/null 2>&1; then
    export PAGER="less"
  fi
fi  # End interactive-only block

# In case ack is named ack-grep
if [ -x /usr/bin/ack-grep ] ; then
  alias ack='/usr/bin/ack-grep'
fi

# I want these first always
PATH="${HOME}/bin:${PATH}"
if [[ "$(uname)" == "Darwin" ]]; then
  PATH="${HOME}/bin/macos:${PATH}"
fi

# Load any local settings
source_if_existing $HOME/.zshrc.local

# separate interactive block based on .zshrc.local
if [[ $- == *i* ]] ; then
  # Set prompt based on local settings
  if test -f "${HOME}/.zprompt" ; then
    THEME=${THEME:=$(cat "${HOME}/.zprompt")}
  fi
  if command -v starship >/dev/null 2>&1 ; then
    : ${THEME:=starship}
    if [ "${THEME}" = "starship" ] ; then
      eval "$(starship init zsh)"
    fi
  fi
  prompt "${THEME:-matir}" >/dev/null 2>&1
fi

# Cleanup PATH
typeset -U PATH

if [[ -n "$ZSH_PROFILE" ]]; then
  zshrc_end_time=$EPOCHREALTIME
  # Calculation in ms using zsh floating point math
  elapsed_ms=$(( (zshrc_end_time - zshrc_start_time) * 1000 ))
  printf "zshrc done: %.0fms\n" "$elapsed_ms"
  zprof
fi
