#!/usr/bin/env bash
#
# rebuild.sh — Rebuild the Claude Code + Obsidian vault stack on a fresh Mac.
#
# Safe to run more than once (idempotent): it skips anything already done and
# never overwrites your existing files. It does the deterministic parts
# (installs, folders, status line, plugins, memory symlink) and prints the
# handful of manual steps it can't do for you (browser logins) at the end.
#
# Usage:
#   bash rebuild.sh                       # vault at ~/Documents/MyVault
#   bash rebuild.sh ~/Documents/Claude    # custom vault path
#
# First run installs Claude Code, then asks you to run `claude login`.
# After you log in, run this script again to finish the rest.

set -uo pipefail

VAULT="${1:-$HOME/Documents/MyVault}"
SETTINGS="$HOME/.claude/settings.json"
STATUSLINE="$HOME/.claude/statusline-command.sh"

# ---- pretty output helpers --------------------------------------------------
bold=$(tput bold 2>/dev/null || true); reset=$(tput sgr0 2>/dev/null || true)
green=$(tput setaf 2 2>/dev/null || true); yellow=$(tput setaf 3 2>/dev/null || true)
red=$(tput setaf 1 2>/dev/null || true)
ok()   { printf "%s✓%s %s\n" "$green" "$reset" "$1"; }
skip() { printf "  %s· %s%s\n" "$yellow" "$1" "$reset"; }
warn() { printf "%s!%s %s\n" "$yellow" "$reset" "$1"; }
err()  { printf "%s✘%s %s\n" "$red" "$reset" "$1"; }
head() { printf "\n%s== %s ==%s\n" "$bold" "$1" "$reset"; }

# ---- PHASE 1: prerequisites -------------------------------------------------
head "Phase 1 — Prerequisites"

# Xcode Command Line Tools (needed before Homebrew on a fresh Mac)
if ! xcode-select -p >/dev/null 2>&1; then
  warn "Xcode Command Line Tools missing. Launching the installer..."
  warn "Click 'Install' in the popup, wait for it to finish, then re-run this script."
  xcode-select --install || true
  exit 0
else
  ok "Xcode Command Line Tools present"
fi

# Homebrew
if ! command -v brew >/dev/null 2>&1; then
  warn "Installing Homebrew (you'll be asked for your Mac password)..."
  /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  # Add brew to PATH for Apple Silicon and Intel
  if [ -x /opt/homebrew/bin/brew ]; then eval "$(/opt/homebrew/bin/brew shellenv)"; fi
  if [ -x /usr/local/bin/brew ]; then eval "$(/usr/local/bin/brew shellenv)"; fi
else
  ok "Homebrew present"
fi

# Core CLIs (jq is required for the status line; git+gh are broadly useful)
for pkg in git gh jq; do
  if brew list "$pkg" >/dev/null 2>&1 || command -v "$pkg" >/dev/null 2>&1; then
    skip "$pkg already installed"
  else
    warn "Installing $pkg..."; brew install "$pkg" && ok "$pkg installed"
  fi
done

# Claude Code (native installer — no Node required, auto-updates)
if ! command -v claude >/dev/null 2>&1; then
  warn "Installing Claude Code (native installer)..."
  curl -fsSL https://claude.ai/install.sh | bash
  # The installer puts claude at ~/.local/bin — make sure it's on PATH now
  export PATH="$HOME/.local/bin:$PATH"
fi

if ! command -v claude >/dev/null 2>&1; then
  err "Claude Code didn't land on your PATH. Open a new terminal and re-run this script."
  exit 1
fi
ok "Claude Code: $(claude --version 2>/dev/null || echo installed)"

# ---- auth checkpoint --------------------------------------------------------
# Plugin installs require an authenticated session. We can't script the browser
# login, so if this looks like a brand-new install, stop here.
if [ ! -f "$HOME/.claude.json" ] && [ ! -d "$HOME/.claude/sessions" ]; then
  head "Log in, then re-run"
  echo "Claude Code is installed but not logged in yet."
  echo "Run this once in your terminal (it opens your browser):"
  echo
  echo "    ${bold}claude login${reset}"
  echo
  echo "Then run this script again to finish setup."
  exit 0
fi

# ---- PHASE 2: vault structure ----------------------------------------------
head "Phase 2 — Vault structure at $VAULT"
mkdir -p "$VAULT"/{companies,projects,.agents,.claude/skills,_stack}
ok "Folders created"

write_if_absent() {  # $1 = path, stdin = contents
  if [ -f "$1" ]; then skip "$(basename "$1") exists, leaving it alone"; else cat > "$1"; ok "Created $(basename "$1")"; fi
}

write_if_absent "$VAULT/CLAUDE.md" <<'EOF'
# Claude Context — Your Name

## Who I Am
1-2 sentences: your role, what you do, how you make decisions.

## How to Work With Me
- Be direct. Give a recommendation, not a menu of options.
- Match format to task — bullets for lists, prose for strategy.
- Flag tradeoffs but skip the basics.

## What I Need Help With
- (recurring task types go here)

## My Companies / Projects
| Name | Role | Status | Folder |
|---|---|---|---|
| Example Co | Owner | Active | [companies/example/](companies/example/) |

## My Personal Profile
→ [me.md](me.md)

## Setup notes
- `_memory` is a symlink to ~/.claude/projects/<encoded-path>/memory/.
  Recreate after a fresh clone by re-running rebuild.sh, or manually:
  ln -s ~/.claude/projects/$(echo "$PWD" | sed 's#[/.]#-#g')/memory _memory
EOF

write_if_absent "$VAULT/me.md" <<'EOF'
# Your Name — Personal Profile

## Background
(a few sentences)

## Technical Level
(how much code comfort — shapes how Claude explains things)

## Working Style
(fast/direct? detail-oriented? etc.)

## Current Priorities
- (what you're focused on right now)
EOF

write_if_absent "$VAULT/.gitignore" <<'EOF'
# Secrets — never commit
**/.env
**/.env.*
!**/.env.example

# Claude Code transient
.playwright-mcp/
.last-cleanup
_stack/snapshot-latest.md

# Tooling
node_modules/
__pycache__/
.venv/

# OS / editor
.DS_Store
.vscode/
.idea/

# Obsidian transient
.obsidian/workspace.json
.obsidian/cache/
EOF

write_if_absent "$VAULT/_stack/snapshot.sh" <<'EOF'
#!/usr/bin/env bash
# Prints the current state of the Claude Code stack. Read-only.
set -u
echo "# Stack Snapshot — $(date '+%Y-%m-%d %H:%M %Z')"; echo
echo "## MCP Servers";       claude mcp list 2>&1
echo "## Claude Code";       claude --version 2>&1
echo "## Installed Plugins"; claude plugin list 2>&1
echo "## User Skills";       ls ~/.claude/skills/ 2>/dev/null | sort
echo "## Key CLIs"
for c in node npm python3 pipx gh git jq claude; do
  command -v "$c" >/dev/null 2>&1 && printf -- "- %s: %s\n" "$c" "$("$c" --version 2>&1 | head -1)"
done
echo "## Homebrew outdated"; brew outdated 2>/dev/null | head -30
EOF
chmod +x "$VAULT/_stack/snapshot.sh" 2>/dev/null && ok "snapshot.sh is executable"

# ---- PHASE 3: status line ---------------------------------------------------
head "Phase 3 — Status line"
mkdir -p "$HOME/.claude"
if [ -f "$STATUSLINE" ]; then
  skip "statusline-command.sh exists"
else
cat > "$STATUSLINE" <<'EOF'
#!/usr/bin/env bash
# ~/.claude/statusline-command.sh — shows: dir | model | context usage
input=$(cat)
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // ""')
dir=$(basename "$cwd")
model=$(echo "$input" | jq -r '.model.display_name // .model.id // "unknown"')
used_pct=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
total=$(echo "$input" | jq -r '.context_window.context_window_size // 200000')
tokens=$(echo "$input" | jq -r '.context_window.total_input_tokens // 0')
if [ -n "$used_pct" ]; then
  used_int=$(printf '%.0f' "$used_pct")
  if [ "$total" -ge 1000000 ]; then tf=$(echo "$total" | awk '{printf "%.0fM",$1/1000000}'); else tf=$(echo "$total" | awk '{printf "%.0fK",$1/1000}'); fi
  tk=$(echo "$tokens" | awk '{printf "%.0fK",$1/1000}'); ctx="${tk}/${tf} (${used_int}%)"
else ctx="--"; fi
printf "%s  |  %s  |  ctx: %s\n" "$dir" "$model" "$ctx"
EOF
  ok "Created statusline-command.sh"
fi
chmod +x "$STATUSLINE"

# Merge the statusLine key into settings.json without clobbering existing keys
tmp=$(mktemp)
SL='{"statusLine":{"type":"command","command":"bash ~/.claude/statusline-command.sh"}}'
if [ -f "$SETTINGS" ]; then
  if jq -e '.statusLine' "$SETTINGS" >/dev/null 2>&1; then
    skip "settings.json already has a statusLine"
  else
    jq ". + $SL" "$SETTINGS" > "$tmp" && mv "$tmp" "$SETTINGS" && ok "Added statusLine to settings.json"
  fi
else
  echo "$SL" | jq . > "$SETTINGS" && ok "Created settings.json with statusLine"
fi
rm -f "$tmp" 2>/dev/null || true

# ---- PHASE 4: plugins (skills bundles) -------------------------------------
head "Phase 4 — Skill & plugin bundles"
add_market() { claude plugin marketplace add "$1" >/dev/null 2>&1 && ok "marketplace: $1" || skip "marketplace $1 (already added or unreachable)"; }
inst() { claude plugin install "$1" -s user >/dev/null 2>&1 && ok "plugin: $1" || skip "plugin $1 (already installed or failed)"; }

add_market anthropics/skills
add_market coreyhaines31/marketingskills
add_market kepano/obsidian-skills
# superpowers + codex live in marketplaces Claude Code ships with knowledge of;
# add their sources explicitly to be safe:
add_market obra/superpowers-marketplace
add_market openai/codex-plugin-cc

inst document-skills@anthropic-agent-skills
inst example-skills@anthropic-agent-skills
inst marketing-skills@marketingskills
inst obsidian@obsidian-skills
inst superpowers@superpowers-marketplace
# Codex is optional — uncomment if you use it:
# inst codex@openai-codex

# ---- PHASE 5: memory symlink ------------------------------------------------
head "Phase 5 — Memory symlink"
ENC=$(echo "$VAULT" | sed 's#[/.]#-#g')
MEMDIR="$HOME/.claude/projects/$ENC/memory"
mkdir -p "$MEMDIR"
if [ -L "$VAULT/_memory" ] || [ -e "$VAULT/_memory" ]; then
  skip "_memory already exists"
else
  ln -s "$MEMDIR" "$VAULT/_memory" && ok "Linked _memory -> $MEMDIR"
fi

# ---- PHASE 6: manual steps --------------------------------------------------
head "Done — a few things only you can do"
cat <<EOF

1. ${bold}Obsidian${reset} (free; Sync is \$4/mo if you want multi-device)
   - Download: https://obsidian.md/download
   - Open folder as vault → choose: $VAULT
   - Settings → Community plugins → turn off Restricted mode →
     Browse → install "Dataview" → Enable.

2. ${bold}VS Code${reset} (free)
   - Download: https://code.visualstudio.com/download
   - Extensions (⌘⇧X) → search "Claude Code" → Install → sign in.
   - Open this vault:  code "$VAULT"

3. ${bold}Connect MCPs${reset} — the free ones live at claude.ai (you need a
   paid Claude plan, \$17–20/mo, which already includes Claude Code):
   https://claude.ai/settings/connectors
   Connect any you use: Slack, Notion, Gmail, Google Drive, Google Calendar,
   Canva, Klaviyo, Shopify.

   Local MCPs (free, optional) — run these in your terminal:
     claude mcp add -s user playwright -- npx -y @playwright/mcp@latest --user-data-dir ~/.cache/playwright-meta-profile
     # Google Analytics (needs a Google service-account JSON):
     # claude mcp add -s user google-analytics -e GOOGLE_APPLICATION_CREDENTIALS=/full/path/key.json -- pipx run analytics-mcp

   Paid MCPs (optional):
     Meta + TikTok ads via Pipeboard — sign up at https://pipeboard.co, then:
     claude mcp add -s user --transport http meta-ads   https://mcp.pipeboard.co/meta-ads-mcp
     claude mcp add -s user --transport http tiktok-ads https://tiktok-ads.mcp.pipeboard.co

4. ${bold}Verify${reset}:
     claude mcp list      # MCPs and their status
     claude plugin list   # installed plugins
     cd "$VAULT" && claude   # launch — status line should show the folder name

EOF
ok "Rebuild script finished."
