#!/usr/bin/env bash
set -euo pipefail
# Simple theme switcher for WezTerm integration and other apps.
# Usage: theme-switcher [dark|light|toggle]

# --- Configuration & Initialization ---
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}"
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}"
CACHE_FILE="$CACHE_DIR/current_theme"
mkdir -p "$CACHE_DIR" 2>/dev/null || true

# --- Helper Functions ---

# Resolve symlinks to actual files
resolve_symlink() {
	local file="$1"
	[[ ! -L "$file" ]] && echo "$file" && return

	# Use 'realpath' if available for reliability
	if command -v realpath >/dev/null 2>&1; then
		realpath "$file"
	# Fallback for macOS and others
	elif [[ "$OSTYPE" == "darwin"* ]]; then
		local target
		target=$(readlink "$file")
		[[ "$target" != /* ]] && target="$(dirname "$file")/$target"

		# Recurse if the link target is also a link
		if [[ -L "$target" ]]; then
			resolve_symlink "$target"
		else
			echo "$target"
		fi
	# General fallback for Linux that might not have 'readlink -f'
	else
		readlink -f "$file" 2>/dev/null || echo "$file"
	fi
}

# Detect system theme (macOS/Gnome)
detect_theme() {
	if [[ "$OSTYPE" == "darwin"* ]]; then
		# Check for AppleInterfaceStyle: Dark or Light
		defaults read -g AppleInterfaceStyle 2>/dev/null | grep -qi "Dark" && echo "dark" || echo "light"
	elif command -v gsettings >/dev/null 2>&1; then
		# Check Gnome color-scheme
		gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | grep -qi 'dark' && echo "dark" || echo "light"
	else
		# Default to dark on unknown systems/environments
		echo "dark"
	fi
}

# Get current mode (cached or detected)
get_mode() {
	if [[ -f "$CACHE_FILE" ]]; then
		local cached
		# Read file, trim whitespace
		cached=$(<"$CACHE_FILE")
		cached="${cached//[[:space:]]/}"
		# Validate content before returning
		[[ "$cached" =~ ^(dark|light)$ ]] && echo "$cached" && return
	fi
	detect_theme
}

# Update a config file using a regex pattern
update_config() {
	local config_file="$1"
	local pattern_regex="$2" # The pattern to search for (e.g., 'key = ".*"')
	local dark_val="$3"      # The replacement string for dark mode
	local light_val="$4"     # The replacement string for light mode

	[[ ! -f "$config_file" ]] && return 0

	local mode="${TARGET_MODE:-$(get_mode)}"
	local replacement="$dark_val"
	[[ "$mode" != "dark" ]] && replacement="$light_val"

	local target_file
	target_file=$(resolve_symlink "$config_file")

	# Check if the target file exists and is writable
	[[ ! -f "$target_file" || ! -w "$target_file" ]] && return 0

	# Check if the pattern exists in the file before trying to replace
	# NOTE: Using 'grep -q' with the search pattern regex to verify existence
	if grep -qE "$pattern_regex" "$target_file" 2>/dev/null; then
		# Use a safe delimiter (e.g., '#') for sed to avoid conflicts with paths/values
		local sed_command="s|${pattern_regex}|${replacement}|g"

		if [[ "$OSTYPE" == "darwin"* ]]; then
			# macOS sed requires an empty string for the backup extension
			sed -i '' "$sed_command" "$target_file" 2>/dev/null
		else
			# Linux sed (GNU sed)
			sed -i "$sed_command" "$target_file" 2>/dev/null
		fi

		# Only echo success if sed was run and likely succeeded
		echo "✓ ${config_file##*/}"
	fi
}

# Update zoxide FZF colors in shell config
update_zoxide() {
	command -v zoxide >/dev/null 2>&1 || return 0

	local mode="${TARGET_MODE:-$(get_mode)}"
	local shell_configs=()

	# Detect all standard shell config files
	[[ -f "$HOME/.zshrc" ]] && shell_configs+=("$HOME/.zshrc")
	[[ -f "$HOME/.bashrc" ]] && shell_configs+=("$HOME/.bashrc")
	[[ -f "$HOME/.bash_profile" ]] && shell_configs+=("$HOME/.bash_profile")

	[[ ${#shell_configs[@]} -eq 0 ]] && return 0

	# Define FZF opts based on mode (quotes are tricky, use a function for safety)
	local fzf_opts
	if [[ "$mode" == "dark" ]]; then
		# Corrected for easier reading/maintenance
		fzf_opts="--height 40% --layout=reverse --border --preview-window=down:3:wrap --color=fg:#f8f8f2,bg:#2a2f3b,hl:#f92672,fg+:#f8f8f2,bg+:#49483e,hl+:#f92672,info:#a6e22e,prompt:#66d9ef,pointer:#f92672,marker:#a6e22e,spinner:#a6e22e,header:#66d9ef"
	else
		fzf_opts="--height 40% --layout=reverse --border --preview-window=down:3:wrap --color=fg:#586e75,bg:#fdf6e3,hl:#268bd2,fg+:#073642,bg+:#eee8d5,hl+:#268bd2,info:#859900,prompt:#268bd2,pointer:#cb4b16,marker:#859900,spinner:#859900,header:#268bd2"
	fi

	# The replacement line to insert/update
	local export_line="export _ZO_FZF_OPTS=\"$fzf_opts\""

	for shell_config in "${shell_configs[@]}"; do
		# 1. Update existing line (handles potential existing spacing/quotes)
		local pattern_regex="^export[[:space:]]+_ZO_FZF_OPTS=.*"

		if grep -qE "$pattern_regex" "$shell_config" 2>/dev/null; then
			if [[ "$OSTYPE" == "darwin"* ]]; then
				sed -i '' "s|${pattern_regex}|${export_line}|" "$shell_config"
			else
				sed -i "s|${pattern_regex}|${export_line}|" "$shell_config"
			fi
		# 2. Add new line (prefer insertion before zoxide init for functionality)
		elif grep -q "zoxide init" "$shell_config" 2>/dev/null; then
			# Use sed to insert the line before the first 'zoxide init'
			if [[ "$OSTYPE" == "darwin"* ]]; then
				# macOS sed is tricky; this might not work perfectly on all versions
				sed -i '' "/zoxide init/i\\
${export_line}" "$shell_config"
			else
				# GNU sed: /pattern/i insert_text
				sed -i "/zoxide init/i\\$export_line" "$shell_config"
			fi
		# 3. Fallback: Append to the end
		else
			echo "" >>"$shell_config"
			echo "# Zoxide FZF theme colors (managed by theme-switcher)" >>"$shell_config"
			echo "$export_line" >>"$shell_config"
		fi

		echo "✓ zoxide (${shell_config##*/})"
	done
}

# Find the btop themes path (more robust)
get_btop_path() {
	local btop_path=""
	# 1. Standard XDG Data Home (most common for user installs)
	if [[ -d "${XDG_DATA_HOME:-$HOME/.local/share}/btop/themes" ]]; then
		btop_path="${XDG_DATA_HOME:-$HOME/.local/share}/btop/themes"
	# 2. Homebrew on macOS (Cellar path is complex/versioned)
	elif [[ "$OSTYPE" == "darwin"* ]]; then
		local cellar_path
		# Use 'find' starting from common Homebrew locations, looking for 'btop/themes'
		cellar_path=$(find /opt/homebrew/Cellar/ /usr/local/Cellar/ -type d -name "btop" -prune -exec find {} -type d -name themes \; 2>/dev/null | head -1)
		[[ -n "$cellar_path" ]] && btop_path="$cellar_path"
	# 3. Standard system installs (Debian/RPM/etc)
	elif [[ -d "/usr/share/btop/themes" ]]; then
		btop_path="/usr/share/btop/themes"
	elif [[ -d "/usr/local/share/btop/themes" ]]; then
		btop_path="/usr/local/share/btop/themes"
	fi
	echo "$btop_path"
}

# --- Main Logic ---

main() {
	local mode="${TARGET_MODE:-$(get_mode)}"

	# Cache the mode
	echo "$mode" >"$CACHE_FILE" 2>/dev/null || true
	echo "Switching to $mode mode..."

	# Update configs in parallel for speed

	# 1. Starship
	{
		update_config \
			"$CONFIG_DIR/starship.toml" \
			'palette = ".*"' \
			'palette = "monokai_pro"' \
			'palette = "solarized_light"'
	} &

	# 2. Btop
	{
		local btop_path
		btop_path=$(get_btop_path)

		if [[ -n "$btop_path" ]]; then
			# Ensure the theme is referenced only by its name in the replacement, not the full path,
			# as btop.conf should only contain the name unless the theme is custom/outside its path.
			# However, since you are referencing files outside the config dir, we keep the path structure.
			update_config \
				"$CONFIG_DIR/btop/btop.conf" \
				'color_theme = ".*"' \
				"color_theme = \"monokai.theme\"" \
				"color_theme = \"solarized_light.theme\""
		else
			echo "✗ btop (Could not determine Btop themes path)"
		fi
	} &

	# 3. AeroSpace (macOS only)
	{
		if [[ "$OSTYPE" == "darwin"* ]]; then
			# Pattern: matches the full exec-and-forget line
			local pattern_regex_aerospace="exec-and-forget borders active_color=0x[0-9a-fA-F]{8} inactive_color=0x[0-9a-fA-F]{8} width=[0-9.]+"

			# Replacement: The exact, correct command with colors for dark/light
			local dark_replacement="exec-and-forget borders active_color=0xfff5f5f5 inactive_color=0xff2a2f3b width=5.0"
			local light_replacement="exec-and-forget borders active_color=0xff268BD2 inactive_color=0xff93A1A1 width=5.0"

			update_config \
				"$CONFIG_DIR/aerospace/aerospace.toml" \
				"$pattern_regex_aerospace" \
				"$dark_replacement" \
				"$light_replacement"

			# Immediately apply the borders command via 'aerospace' binary (requires it to be in PATH)
			if command -v aerospace >/dev/null 2>&1; then
				if [[ "$mode" == "light" ]]; then
					aerospace "$light_replacement" 2>/dev/null || true
				else
					aerospace "$dark_replacement" 2>/dev/null || true
				fi
				echo "✓ AeroSpace (Borders applied)"
			else
				echo "✓ AeroSpace (Borders updated in config)"
			fi
		fi
	} &

	# 4. Zoxide/FZF
	{
		update_zoxide
	} &

	# Wait for all background jobs to finish
	wait

	echo "Done!"
	echo ""
	echo "Note: Restart your shell or run 'source ~/.zshrc' (or ~/.bashrc) to apply zoxide colors."
}

# --- Argument Parsing ---

case "${1:-}" in
"dark" | "light")
	export TARGET_MODE="$1"
	;;
"toggle")
	current=$(get_mode)
	export TARGET_MODE
	TARGET_MODE=$([[ "$current" == "dark" ]] && echo "light" || echo "dark")
	;;
*)
	# No args or invalid - auto-detect
	;;
esac

# Execute main function
main
