#!/usr/bin/env bash
set -euo pipefail

trap 'echo "==> Script failed at line $LINENO"' ERR

# To optionally install slack:
# $ curl -fsSL quietmind.sh | bash -s -- --slack

sudo -v
while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &

echo "==> quietmind macOS bootstrap starting"

# Detect macOS
if [[ "$(uname)" != "Darwin" ]]; then
  echo "This bootstrap currently supports macOS only."
  exit 1
fi

# -------------------------------------------------- #
# Detect flags

INSTALL_SLACK=false

for arg in "$@"; do
  case $arg in
    --slack) INSTALL_SLACK=true ;;
  esac
done

# -------------------------------------------------- #
# Xcode CLI tools
if ! xcode-select -p >/dev/null 2>&1; then
  echo "==> Installing Xcode Command Line Tools (a prompt may appear)"
  xcode-select --install || true
fi

# XCode license agreement
if xcodebuild -version >/dev/null 2>&1; then
  sudo xcodebuild -license accept
fi

# -------------------------------------------------- #
# macOS System Configuration Directives
echo "==> Configuring macOS defaults"

# Mouse
defaults write NSGlobalDomain com.apple.swipescrolldirection -bool false

# Keyboard
defaults write NSGlobalDomain KeyRepeat -int 2
defaults write NSGlobalDomain InitialKeyRepeat -int 15

# Trackpad
defaults write NSGlobalDomain com.apple.trackpad.scaling -float 2
defaults write com.apple.AppleMultitouchTrackpad Clicking -bool true
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
defaults write com.apple.AppleMultitouchTrackpad TrackpadThreeFingerDrag -bool true
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadThreeFingerDrag -bool true
defaults write com.apple.dock showAppExposeGestureEnabled -bool true

# Dock
defaults write com.apple.dock tilesize -int 72
defaults write com.apple.dock magnification -bool true
defaults write com.apple.dock largesize -int 115
defaults write com.apple.dock autohide -bool true
defaults write com.apple.dock show-recents -bool false

# Desktop icons
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool false
defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool false
defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool false
defaults write com.apple.finder ShowMountedServersOnDesktop -bool false

# Widgets
defaults write com.apple.WindowManager AlwaysHideWidgets -bool true

# Mission Control
defaults write com.apple.dock mru-spaces -bool false
defaults write NSGlobalDomain AppleSpacesSwitchOnActivate -bool false
defaults write com.apple.dock dragging-into-spaces -bool false

# Stage Manager - click wallpaper only in stage manager
defaults write com.apple.WindowManager EnableStandardClickToShowDesktop -bool false

# Screenshots
mkdir -p ~/Pictures/Screenshots
defaults write com.apple.screencapture location ~/Pictures/Screenshots
defaults write com.apple.screencapture disable-shadow -bool true

# Window dragging to spaces delay
defaults write com.apple.dock workspaces-edge-delay -float 3

# Disable recent items
defaults write com.apple.recentitems RecentApplications -dict MaxAmount 0
defaults write com.apple.recentitems RecentDocuments -dict MaxAmount 0
defaults write com.apple.recentitems RecentServers -dict MaxAmount 0

# Disable .DS_Store on network drives
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true

# save to disk not iCloud by default
defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false

# "Smart" characters
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false

# Screensaver
defaults write com.apple.screensaver idleTime -int 300
defaults write com.apple.screensaver moduleName -string "Aerial"
defaults write com.apple.screensaver modulePath -string "/Library/Screen Savers/Aerial.saver"
if [ -f ~/.config/aerial/prefs.plist ]; then
  defaults import com.apple.ScreenSaver.Aerial ~/.config/aerial/prefs.plist
fi

# Preview
defaults write com.apple.Preview NSRecentDocumentsLimit 0
defaults write com.apple.Preview.LSSharedFileList RecentDocuments -dict-add MaxAmount 0

# TextEdit: open new plain text file by default
defaults write com.apple.TextEdit NSShowAppCentricOpenPanelInsteadOfUntitledFile -bool false
defaults write com.apple.TextEdit RichText -bool false
defaults write com.apple.TextEdit PlainTextFontSize -int 14
defaults write com.apple.TextEdit NSRecentDocumentsLimit 0

# AirDrop
defaults write com.apple.sharingd DiscoverableMode -string "Off"

# Handoff
defaults write ~/Library/Preferences/ByHost/com.apple.coreservices.useractivityd.plist ActivityAdvertisingAllowed -bool NO
defaults write ~/Library/Preferences/ByHost/com.apple.coreservices.useractivityd.plist ActivityReceivingAllowed -bool NO

# Finder
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
defaults write com.apple.finder ShowPathbar -bool true
defaults write com.apple.finder ShowStatusBar -bool true
defaults write com.apple.finder NewWindowTarget -string "PfLo"
defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/Downloads/"

# Apply changes to Dock
echo "==> Restarting macOS Dock"
killall Dock || true

# Apply changes to Finder
echo "==> Restarting macOS Finder"
killall Finder || true

# Apply changes to UI
echo "==> Restarting macOS UI Server"
killall SystemUIServer || true

# Apply changes to useractivityd
echo "==> Restarting macOS User Activity Daemon"
killall useractivityd || true

# -------------------------------------------------- #
# Homebrew
if ! command -v brew >/dev/null 2>&1; then
  echo "==> Installing Homebrew"
  NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
fi

# Ensure brew is on PATH (Apple Silicon / Intel)
if [ -x /opt/homebrew/bin/brew ]; then
  eval "$(/opt/homebrew/bin/brew shellenv)"
elif [ -x /usr/local/bin/brew ]; then
  eval "$(/usr/local/bin/brew shellenv)"
fi

echo "==> Updating Homebrew"
brew update

# -------------------------------------------------- #
# Dotfiles (HTTPS so it works before SSH keys exist)
if [ ! -d "$HOME/.dotfiles" ]; then
  echo "==> Cloning dotfiles"
  git clone --bare https://github.com/ezrafree/dotfiles.git "$HOME/.dotfiles"
fi

echo "==> Checking out dotfiles"
git --git-dir="$HOME/.dotfiles" --work-tree="$HOME" config --local status.showUntrackedFiles no
if ! git --git-dir="$HOME/.dotfiles" --work-tree="$HOME" checkout; then
  echo "==> Dotfiles checkout had conflicts (existing files). Continuing."
  echo "    Tip: review with: git --git-dir=\$HOME/.dotfiles --work-tree=\$HOME status"
fi

# -------------------------------------------------- #
# Phoenix + Karabiner-Elements
mkdir -p "$HOME/.config"

if [ ! -d "$HOME/.config/phoenix" ]; then
  echo "==> Cloning Phoenix config"
  git clone https://github.com/ezrafree/phoenix-config.git "$HOME/.config/phoenix"
  cp "$HOME/.config/phoenix/config/example.config.js" "$HOME/.config/phoenix/config/config.js"
fi

if [ ! -d "$HOME/.config/karabiner" ]; then
  echo "==> Cloning Karabiner-Elements config"
  git clone https://github.com/ezrafree/karabiner-config.git "$HOME/.config/karabiner"
fi

# -------------------------------------------------- #
# Brew bundle
if [ -f "$HOME/Brewfile" ]; then
  echo "==> Installing Brewfile packages"
  brew bundle --file "$HOME/Brewfile" --no-upgrade || true
else
  echo "==> No ~/Brewfile found. Skipping brew bundle."
fi

# -------------------------------------------------- #
# Install Slack

if [ "$INSTALL_SLACK" = true ]; then
  echo "==> Installing Slack"
  brew install --cask slack
fi

# -------------------------------------------------- #
# Install Volta
if ! command -v volta >/dev/null 2>&1; then
  echo "==> Installing Volta"
  curl -fsSL https://get.volta.sh | bash -s -- --skip-setup
  export VOLTA_HOME="$HOME/.volta"
  export PATH="$VOLTA_HOME/bin:$PATH"
fi

# Install Node via Volta
volta install node

# Install TypeScript via Volta
volta install typescript

# Install Yarn 1.x via Volta
volta install yarn@1

# -------------------------------------------------- #
# Install vim-plug
if [ ! -f ~/.vim/autoload/plug.vim ]; then
  curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
fi

# -------------------------------------------------- #
# Install Neovim plugins
if command -v nvim >/dev/null 2>&1; then
  echo "==> Installing Neovim plugins"
  nvim --headless +PlugInstall +qall || true
fi

# Install python
if command -v pyenv >/dev/null; then
  echo "==> Installing Python"
  pyenv install -s 3
  pyenv global 3
fi

# -------------------------------------------------- #
# Install Global NPM Packages
if [ -f "$HOME/.config/bin/global-npm.sh" ]; then
  echo "==> Installing global NPM packages"
  bash "$HOME/.config/bin/global-npm.sh"
else
  echo "==> Skipping global NPM packages (~/.config/bin/global-npm.sh not found)"
fi

# -------------------------------------------------- #
# Install App Store apps with `mas`
if command -v mas >/dev/null 2>&1; then
  if mas list >/dev/null 2>&1; then
    bash "$HOME/.config/bin/global-mas.sh"
  else
    echo "==> Skipping App Store installs (not signed into App Store)"
    echo "    Sign in to the App Store and run:"
    echo "    bash ~/.config/bin/global-mas.sh"
  fi
else
  echo "==> Skipping App Store installs (mas not installed)"
fi

# -------------------------------------------------- #
echo "==> Setting up scheduled tasks"

# Create LaunchAgents directory
mkdir -p ~/Library/LaunchAgents

# LaunchAgent plists
cat > ~/Library/LaunchAgents/com.ezra.cleanup-downloads.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key><string>com.ezra.cleanup-downloads</string>
    <key>ProgramArguments</key>
    <array>
      <string>${HOME}/.config/bin/cleanup_downloads.sh</string>
    </array>
    <key>StartInterval</key><integer>14400</integer>
    <key>RunAtLoad</key><true/>
    <key>StandardOutPath</key><string>/tmp/cleanup-downloads.out.log</string>
    <key>StandardErrorPath</key><string>/tmp/cleanup-downloads.err.log</string>
  </dict>
</plist>
EOF

cat > ~/Library/LaunchAgents/com.ezra.cleanup-screenshots.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key><string>com.ezra.cleanup-screenshots</string>
    <key>ProgramArguments</key>
    <array>
      <string>${HOME}/.config/bin/cleanup_screenshots.sh</string>
    </array>
    <key>StartInterval</key><integer>14400</integer>
    <key>RunAtLoad</key><true/>
    <key>StandardOutPath</key><string>/tmp/cleanup-screenshots.out.log</string>
    <key>StandardErrorPath</key><string>/tmp/cleanup-screenshots.err.log</string>
  </dict>
</plist>
EOF

# Load agents (unload first to make it idempotent)
launchctl unload ~/Library/LaunchAgents/com.ezra.cleanup-downloads.plist 2>/dev/null || true
launchctl unload ~/Library/LaunchAgents/com.ezra.cleanup-screenshots.plist 2>/dev/null || true
launchctl load -w ~/Library/LaunchAgents/com.ezra.cleanup-downloads.plist
launchctl load -w ~/Library/LaunchAgents/com.ezra.cleanup-screenshots.plist

# -------------------------------------------------- #
# Create the ~/bin/ directory
echo "==> Creating the ~/bin/ directory."
mkdir -p ~/bin/

# -------------------------------------------------- #
# Configure SSH
if [ ! -f ~/.ssh/config ]; then
  echo "==> Creating the ~/.ssh/ directory."
  mkdir -p ~/.ssh
  chmod 700 ~/.ssh
  echo "==> Creating the ~/.ssh/config file."
  cat > ~/.ssh/config << 'EOF'
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
  AddKeysToAgent yes
  UseKeychain yes
EOF
  chmod 600 ~/.ssh/config
fi

# -------------------------------------------------- #
echo "==> Done. Restart Terminal for zsh config to fully load."
if [ ! -f ~/.config/gitconfig ]; then
  echo ""
  echo "==> ACTION REQUIRED: Configure git identity for this machine:"
  echo "    git config --file ~/.config/gitconfig user.name \"Your Name\""
  echo "    git config --file ~/.config/gitconfig user.email \"you@email.com\""
fi
if ! scutil --get HostName >/dev/null 2>&1; then
  echo ""
  echo "==> ACTION REQUIRED: Set this machine's hostname:"
  echo "    sudo scutil --set HostName \"your-hostname\""
  echo "    sudo scutil --set LocalHostName \"your-hostname\""
  echo "    sudo scutil --set ComputerName \"your-hostname\""
fi
echo ""
