#!/bin/bash
# bootstrap.sh - Complete macOS setup script
# Run with: bash bootstrap.sh

set -u  # Error on undefined variables

# ============================================================================
# CONFIGURATION
# ============================================================================

DOTFILES_REPO="git@git.sr.ht:~zachyordy/dotfiles"  # UPDATE THIS
BREWFILE_PATH="$HOME/.Brewfile"  # Or wherever your Brewfile lives
SSH_KEY_URL="https://bootstrap.yord.in/git.sr.ht_ed25519.enc"

# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Track failures
declare -a FAILED_STEPS=()
declare -a WARNINGS=()

# ============================================================================
# HELPER FUNCTIONS
# ============================================================================

print_header() {
	echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
	echo -e "${CYAN}  $1${NC}"
	echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
}

step() {
	echo -e "${BLUE}▶${NC} $1"
}

info() {
	echo -e "${CYAN}ℹ${NC} $1"
}

success() {
	echo -e "${GREEN}✓${NC} $1"
}

warn() {
	echo -e "${YELLOW}⚠${NC} $1"
	WARNINGS+=("$1")
}

error() {
	echo -e "${RED}✗${NC} $1"
	FAILED_STEPS+=("$1")
}

ask_continue() {
	# Skip prompts when stdin is not a terminal (piped from curl)
	if [ ! -t 0 ]; then
		warn "Non-interactive mode detected, continuing automatically..."
		return 0
	fi
	
	read -p "$(echo -e ${YELLOW}Continue? [y/N]:${NC} )" -n 1 -r
	echo
	if [[ ! $REPLY =~ ^[Yy]$ ]]; then
		echo "Exiting."
		exit 0
	fi
}

# ============================================================================
# MAIN INSTALLATION STEPS
# ============================================================================

install_xcode_tools() {
	print_header "Installing macOS Command Line Tools"
	
	if xcode-select -p &> /dev/null; then
		success "Command Line Tools already installed at $(xcode-select -p)"
		return 0
	fi
	
	step "Installing Command Line Tools..."
	echo "This may take a few minutes and will prompt for installation..."
	
	# Trigger installation
	xcode-select --install 2>&1
	
	# Wait for installation to complete
	echo "Waiting for installation to complete..."
	until xcode-select -p &> /dev/null; do
		sleep 5
	done
	
	success "Command Line Tools installed successfully"
}

install_homebrew() {
	print_header "Installing Homebrew"
	
	if command -v brew &> /dev/null; then
		success "Homebrew already installed at $(which brew)"
		step "Updating Homebrew..."
		brew update
		return 0
	fi
	
	step "Installing Homebrew..."
	if /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"; then
		# Add Homebrew to PATH for this session
		if [[ $(uname -m) == 'arm64' ]]; then
			step "Adding Homebrew to PATH (Apple Silicon)..."
			eval "$(/opt/homebrew/bin/brew shellenv)"
		else
			eval "$(/usr/local/bin/brew shellenv)"
		fi
		success "Homebrew installed successfully"
	else
		error "Failed to install Homebrew"
		echo "Visit https://brew.sh for manual installation instructions"
		exit 1
	fi

	# Disable analytics
	step "Disabling Homebrew analytics..."
	brew analytics off
	success "Homebrew analytics disabled"
}

install_essential_tools() {
	print_header "Installing Essential Tools"
	
	local tools=("fish" "yadm" "mas")
	
	for tool in "${tools[@]}"; do
		step "Checking $tool..."
		if command -v "$tool" &> /dev/null; then
			success "$tool already installed"
		elif brew list "$tool" &> /dev/null 2>&1; then
			success "$tool already installed via Homebrew"
		else
			step "Installing $tool..."
			if brew install "$tool"; then
				success "$tool installed successfully"
			else
				error "Failed to install $tool"
				warn "You can retry with: brew install $tool"
			fi
		fi
	done
}

setup_ssh_key() {
	print_header "SSH Key Setup for sr.ht"
	
	local ssh_dir="$HOME/.ssh"
	local key_file="$ssh_dir/ssh-keys/yadm_sr.ht"
	local temp_encrypted="/tmp/yadm_sr.ht.enc.$$"
	local temp_decrypted="/tmp/yadm_sr.ht.$$"
	
	# Check if key already exists
	if [ -f "$key_file" ]; then
		success "SSH key already exists at $key_file"
	else
		# Download and decrypt key
		step "Downloading encrypted SSH key..."
		if ! curl -fsSL "$SSH_KEY_URL" -o "$temp_encrypted" 2>/dev/null; then
			error "Could not download encrypted SSH key"
			exit 1
		fi
		
		success "Encrypted key downloaded"
		
		# Decrypt to temp location
		local attempts=0
		local max_attempts=3
		
		while [ $attempts -lt $max_attempts ]; do
			echo ""
			read -s -p "$(echo -e ${YELLOW}Enter SSH key decryption password:${NC} )" password
			echo ""
			
			if echo "$password" | openssl enc -aes-256-cbc -d -pbkdf2 \
				-in "$temp_encrypted" \
				-out "$temp_decrypted" \
				-pass stdin 2>/dev/null; then
				
				# Set correct permissions BEFORE validation
				chmod 600 "$temp_decrypted"
				
				# Validate it's a valid SSH key
				if ssh-keygen -y -f "$temp_decrypted" > /dev/null 2>&1; then
					# Move to final location
					mkdir -p "$ssh_dir"
					mv "$temp_decrypted" "$key_file"
					chmod 600 "$key_file"
					
					# Generate public key
					ssh-keygen -y -f "$key_file" > "${key_file}.pub"
					chmod 644 "${key_file}.pub"

					# Cleanup temp files explicitly
					rm -f "$temp_encrypted" "$temp_decrypted"
					
					success "SSH key configured successfully"
					break
				else
					error "Decrypted file is not a valid SSH key"
					rm -f "$temp_encrypted" "$temp_decrypted"
					exit 1
				fi
			else
				attempts=$((attempts + 1))
				rm -f "$temp_decrypted"
				if [ $attempts -lt $max_attempts ]; then
					error "Incorrect password. $(($max_attempts - $attempts)) attempts remaining."
				else
					rm -f "$temp_encrypted" "$temp_decrypted"
					error "Failed to decrypt SSH key after $max_attempts attempts"
					exit 1
				fi
			fi
		done

		# Test connection
		step "Testing SSH connection to sr.ht..."
		if ssh -T git@git.sr.ht 2>&1 | grep -q "Hi"; then
			success "SSH connection successful"
		else
			warn "SSH connection test failed"
			echo "Ensure your key is added to sr.ht: https://meta.sr.ht/keys"
			ask_continue
		fi
	fi
	
	# Configure SSH config (runs whether key existed or was just created)
	step "Configuring SSH to use key for sr.ht..."
	
	local ssh_config="$ssh_dir/config"
	
	# Create .ssh directory if needed
	mkdir -p "$ssh_dir"
	
	# Create config if it doesn't exist
	if [ ! -f "$ssh_config" ]; then
		touch "$ssh_config"
		chmod 600 "$ssh_config"
	fi
	
	# Add sr.ht configuration if not already present
	if ! grep -q "Host git.sr.ht" "$ssh_config"; then
		cat >> "$ssh_config" << EOF

# sr.ht configuration
Host git.sr.ht
	IdentityFile ~/.ssh/ssh-keys/yadm_sr.ht
	IdentitiesOnly yes
EOF
		success "SSH config updated for sr.ht"
	else
		success "SSH config already has sr.ht entry"
	fi
}

clone_dotfiles() {
	print_header "Cloning Dotfiles with yadm"
	
	if [ -d "$HOME/.local/share/yadm/repo.git" ]; then
		success "Dotfiles already cloned"
		step "Pulling latest changes..."
		if yadm pull; then
			success "Dotfiles updated"
		else
			warn "Failed to pull updates - continuing anyway"
		fi
	else
		step "Cloning dotfiles from $DOTFILES_REPO..."
		
		# Clone (SSH config handles key selection)
		if yadm clone "$DOTFILES_REPO"; then
			success "Dotfiles cloned successfully"
			
			# Handle conflicts
			if yadm status 2>&1 | grep -q "conflict"; then
				warn "Conflicts detected in dotfiles"
				echo "Run 'yadm status' and 'yadm mergetool' to resolve"
			fi
		else
			error "Failed to clone dotfiles"
			echo "Check that your SSH key is added to sr.ht: https://meta.sr.ht/keys"
			exit 1
		fi
	fi
	
	# Set yadm class if not already set
	if ! yadm config local.class &> /dev/null; then
		echo ""
		step "Configure machine type for yadm alternate files"
		echo "This determines which Brewfile and configs to use"
		echo ""
		echo "1) Local (personal laptop)"
		echo "2) Work (company laptop)"
		echo ""
		read -p "Select [1-2]: " -n 1 -r choice
		echo ""
		
		case $choice in
			1)
				yadm config local.class "Local"
				success "Machine type set to: Local"
				;;
			2)
				yadm config local.class "Work"
				success "Machine type set to: Work"
				;;
			*)
				warn "Invalid choice, defaulting to Local"
				yadm config local.class "Local"
				;;
		esac
	else
		local current_class=$(yadm config local.class)
		success "yadm class already set to: $current_class"
	fi
}

run_brew_bundle() {
	print_header "Installing Packages from Brewfile"
	
	local brewfile_shared="$HOME/.Brewfile"
	local brewfile_class=""
	local brewfile_url="https://bootstrap.yord.in/Brewfile"
	local brewfile_class_url=""
	
	# Determine class-specific Brewfile
	local yadm_class=$(yadm config local.class 2>/dev/null || echo "")
	if [ -n "$yadm_class" ]; then
		brewfile_class="$HOME/.Brewfile.$yadm_class"
		brewfile_class_url="https://bootstrap.yord.in/Brewfile.$yadm_class"
	fi
	
	# Download or check for shared Brewfile
	if [ ! -f "$brewfile_shared" ]; then
		step "Downloading shared Brewfile from $brewfile_shared_url..."
		if curl -fsSL "$brewfile_shared_url" -o "$brewfile_shared" 2>/dev/null; then
			success "Shared Brewfile downloaded"
		else
			warn "Could not download shared Brewfile"
			warn "Skipping package installation"
			return 0
		fi
	else
		success "Shared Brewfile already exists at $brewfile_shared"
	fi
	
	# Download class-specific Brewfile if class is set
	if [ -n "$yadm_class" ]; then
		if [ ! -f "$brewfile_class" ]; then
			step "Downloading $yadm_class-specific Brewfile from $brewfile_class_url..."
			if curl -fsSL "$brewfile_class_url" -o "$brewfile_class" 2>/dev/null; then
				success "$yadm_class-specific Brewfile downloaded"
			else
				info "No $yadm_class-specific Brewfile available (this is fine if you don't need one)"
			fi
		else
			success "$yadm_class-specific Brewfile already exists at $brewfile_class"
		fi
	fi
	
	# Install from shared Brewfile
	step "Installing shared packages from $brewfile_shared..."
	if brew bundle --file="$brewfile_shared"; then
		success "Shared packages installed successfully"
	else
		warn "Some shared packages failed to install"
	fi
	
	# Install from class-specific Brewfile if it exists
	if [ -n "$brewfile_class" ] && [ -f "$brewfile_class" ]; then
		step "Installing $yadm_class-specific packages from $brewfile_class..."
		if brew bundle --file="$brewfile_class"; then
			success "$yadm_class-specific packages installed successfully"
		else
			warn "Some $yadm_class-specific packages failed to install"
		fi
	fi
	
	success "Brewfile installation complete"
}
set_fish_as_default() {
	print_header "Setting Fish as Default Shell"
	
	if ! command -v fish &> /dev/null; then
		warn "Fish not installed, skipping shell change"
		return 0
	fi
	
	local fish_path
	fish_path=$(command -v fish)
	
	if [ "$SHELL" = "$fish_path" ]; then
		success "Fish is already your default shell"
		return 0
	fi
	
	step "Adding fish to /etc/shells if needed..."
	if ! grep -q "$fish_path" /etc/shells; then
		echo "$fish_path" | sudo tee -a /etc/shells
		success "Added $fish_path to /etc/shells"
	else
		success "Fish already in /etc/shells"
	fi
	
	step "Changing default shell to fish..."
	if chsh -s "$fish_path"; then
		success "Default shell changed to fish"
		info "You'll need to restart your terminal for this to take effect"
	else
		error "Failed to change default shell"
		warn "Try manually: chsh -s $fish_path"
	fi
}

apply_macos_preferences() {
	print_header "Applying macOS Preferences"
	
	#step "Setting Terminal preferences..."
	
	# Terminal preferences
	#step "Configuring Terminal.app..."
	
	#success "Terminal preferences applied"
	
	# Optional: Add more defaults write commands here
	# Example dock preferences:
	# step "Configuring Dock..."
	# defaults write com.apple.dock autohide -bool true
	# defaults write com.apple.dock tilesize -int 48
	# killall Dock
	
	# Example Finder preferences:
	# step "Configuring Finder..."
	# defaults write com.apple.finder ShowPathbar -bool true
	# defaults write com.apple.finder AppleShowAllFiles -bool true
	# killall Finder
	
	success "macOS preferences applied"
	info "Some changes may require logging out or restarting"
}

# ============================================================================
# FINAL SUMMARY
# ============================================================================

print_summary() {
	print_header "Bootstrap Summary"
	
	if [ ${#FAILED_STEPS[@]} -eq 0 ] && [ ${#WARNINGS[@]} -eq 0 ]; then
		echo -e "${GREEN}╔════════════════════════════════════════════════════════╗${NC}"
		echo -e "${GREEN}║                                                        ║${NC}"
		echo -e "${GREEN}║         ✨ Bootstrap completed successfully! ✨        ║${NC}"
		echo -e "${GREEN}║                                                        ║${NC}"
		echo -e "${GREEN}╚════════════════════════════════════════════════════════╝${NC}"
		echo ""
		echo -e "${CYAN}Next steps:${NC}"
		echo "  1. Restart your terminal (or run: exec fish)"
		echo "  2. Verify everything works: brew doctor"
		echo "  3. Check yadm status: yadm status"
		echo ""
	else
		echo -e "${YELLOW}╔════════════════════════════════════════════════════════╗${NC}"
		echo -e "${YELLOW}║                                                        ║${NC}"
		echo -e "${YELLOW}║      ⚠  Bootstrap completed with issues  ⚠            ║${NC}"
		echo -e "${YELLOW}║                                                        ║${NC}"
		echo -e "${YELLOW}╚════════════════════════════════════════════════════════╝${NC}"
		echo ""
		
		if [ ${#FAILED_STEPS[@]} -gt 0 ]; then
			echo -e "${RED}Failed steps:${NC}"
			for step in "${FAILED_STEPS[@]}"; do
				echo -e "  ${RED}✗${NC} $step"
			done
			echo ""
		fi
		
		if [ ${#WARNINGS[@]} -gt 0 ]; then
			echo -e "${YELLOW}Warnings:${NC}"
			for warning in "${WARNINGS[@]}"; do
				echo -e "  ${YELLOW}⚠${NC} $warning"
			done
			echo ""
		fi
		
		echo -e "${CYAN}To fix issues:${NC}"
		echo "  - Re-run this script: bash bootstrap.sh"
		echo "  - Or fix individual steps manually and re-run"
		echo ""
	fi
}

# ============================================================================
# MAIN EXECUTION
# ============================================================================

main() {
	clear
	echo -e "${CYAN}"
	cat << "EOF"
╔══════════════════════════════════════════════════════════════╗
║                                                              ║
║                   macOS Bootstrap Script                     ║
║                                                              ║
║  This script will set up your Mac with:                      ║
║    • Homebrew & Command Line Tools                           ║
║    • Fish shell, yadm, mas                                   ║
║    • Your dotfiles from sr.ht                                ║
║    • All packages from your Brewfile                         ║
║    • macOS preferences                                       ║
║                                                              ║
╚══════════════════════════════════════════════════════════════╝
EOF
	echo -e "${NC}"
	
	ask_continue
	
	# Execute all steps
	install_xcode_tools
	install_homebrew
	install_essential_tools
	setup_ssh_key
	clone_dotfiles
	run_brew_bundle
	set_fish_as_default
	apply_macos_preferences
	
	# Show summary
	print_summary
}

# Run the script
main
