#!/usr/bin/env bash

# MyBrag MCP Setup Script
# Configures MyBrag MCP for Claude Desktop and Cursor.

set -euo pipefail

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

SERVER_NAME="mybrag"
MCP_URL="https://www.mybrag.app/api/mcp/mcp"
SETUP_CLAUDE=true
SETUP_CURSOR=true

usage() {
  cat <<EOF
Usage: setup-mcp.sh [options]

Options:
  --claude-only   Configure Claude Desktop only
  --cursor-only   Configure Cursor only
  --help          Show this help message
EOF
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    --claude-only)
      SETUP_CLAUDE=true
      SETUP_CURSOR=false
      ;;
    --cursor-only)
      SETUP_CLAUDE=false
      SETUP_CURSOR=true
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      echo -e "${RED}Unknown option:${NC} $1"
      usage
      exit 1
      ;;
  esac
  shift
done

echo ""
echo -e "${BLUE}╔══════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║         MyBrag MCP Setup Script          ║${NC}"
echo -e "${BLUE}╚══════════════════════════════════════════╝${NC}"
echo ""

OS="unknown"
case "${OSTYPE:-}" in
  darwin*) OS="macos" ;;
  linux-gnu*) OS="linux" ;;
  msys*|cygwin*|win32*) OS="windows" ;;
esac

echo -e "${BLUE}Detected OS:${NC} $OS"
echo -e "${BLUE}MCP endpoint:${NC} $MCP_URL"
echo ""

to_unix_path() {
  local raw_path="$1"
  if [[ "$OS" == "windows" ]] && command -v cygpath >/dev/null 2>&1; then
    cygpath -u "$raw_path"
  else
    printf '%s' "$raw_path"
  fi
}

json_merge() {
  local file="$1"
  local client="$2"
  local temp_file
  temp_file="$(mktemp)"

  if command -v python3 >/dev/null 2>&1 || command -v node >/dev/null 2>&1; then
    json_merge_with_runtime "$file" "$temp_file" "$client"
  elif command -v jq >/dev/null 2>&1; then
    if [ "$client" = "claude" ]; then
      jq --arg name "$SERVER_NAME" --arg url "$MCP_URL" '
        . as $root
        | ($root | if type == "object" then . else {} end)
        | .mcpServers = (.mcpServers // {})
        | .mcpServers[$name] = {
            "command": "npx",
            "args": ["-y", "mcp-remote", $url]
          }
      ' "$file" > "$temp_file"
    else
      jq --arg name "$SERVER_NAME" --arg url "$MCP_URL" '
        . as $root
        | ($root | if type == "object" then . else {} end)
        | .mcpServers = (.mcpServers // {})
        | .mcpServers[$name] = {
            "type": "http",
            "url": $url
          }
      ' "$file" > "$temp_file"
    fi
  else
    rm -f "$temp_file"
    echo -e "${RED}  Could not safely edit JSON.${NC} Install jq, python3, or node and run this script again."
    return 1
  fi

  mv "$temp_file" "$file"
}

json_merge_with_runtime() {
  local file="$1"
  local temp_file="$2"
  local client="$3"

  if command -v python3 >/dev/null 2>&1; then
    CLIENT="$client" SERVER_NAME="$SERVER_NAME" MCP_URL="$MCP_URL" python3 - "$file" > "$temp_file" <<'PY'
import json
import os
import sys

path = sys.argv[1]
client = os.environ["CLIENT"]
name = os.environ["SERVER_NAME"]
url = os.environ["MCP_URL"]

try:
    with open(path, "r", encoding="utf-8") as handle:
        data = json.load(handle)
except (json.JSONDecodeError, FileNotFoundError):
    data = {}

if not isinstance(data, dict):
    data = {}

servers = data.setdefault("mcpServers", {})
if not isinstance(servers, dict):
    servers = {}
    data["mcpServers"] = servers

if client == "claude":
    servers[name] = {
        "command": "npx",
        "args": ["-y", "mcp-remote", url],
    }
else:
    servers[name] = {
        "type": "http",
        "url": url,
    }

json.dump(data, sys.stdout, indent=2)
sys.stdout.write("\n")
PY
  elif command -v node >/dev/null 2>&1; then
    CLIENT="$client" SERVER_NAME="$SERVER_NAME" MCP_URL="$MCP_URL" node - "$file" > "$temp_file" <<'JS'
const fs = require("fs");

const path = process.argv[2];
const client = process.env.CLIENT;
const name = process.env.SERVER_NAME;
const url = process.env.MCP_URL;

let data = {};
try {
  data = JSON.parse(fs.readFileSync(path, "utf8"));
} catch {
  data = {};
}

if (!data || typeof data !== "object" || Array.isArray(data)) {
  data = {};
}

if (!data.mcpServers || typeof data.mcpServers !== "object" || Array.isArray(data.mcpServers)) {
  data.mcpServers = {};
}

data.mcpServers[name] = client === "claude"
  ? { command: "npx", args: ["-y", "mcp-remote", url] }
  : { type: "http", url };

process.stdout.write(JSON.stringify(data, null, 2) + "\n");
JS
  else
    rm -f "$temp_file"
    echo -e "${RED}  Could not safely edit JSON.${NC} Install jq, python3, or node and run this script again."
    return 1
  fi
}

write_config() {
  local file="$1"
  local client="$2"
  local label="$3"

  mkdir -p "$(dirname "$file")"

  if [ ! -f "$file" ]; then
    printf '{}\n' > "$file"
  fi

  if [ -s "$file" ]; then
    cp "$file" "${file}.backup.$(date +%Y%m%d%H%M%S)"
  fi

  if json_merge "$file" "$client"; then
    echo -e "${GREEN}  Configured $label:${NC} $file"
    return 0
  fi

  return 1
}

CLAUDE_CONFIG=""
CURSOR_CONFIG=""

case "$OS" in
  macos)
    CLAUDE_CONFIG="$HOME/Library/Application Support/Claude/claude_desktop_config.json"
    CURSOR_CONFIG="$HOME/.cursor/mcp.json"
    ;;
  linux)
    CLAUDE_CONFIG="$HOME/.config/Claude/claude_desktop_config.json"
    CURSOR_CONFIG="$HOME/.cursor/mcp.json"
    ;;
  windows)
    APPDATA_UNIX="$(to_unix_path "${APPDATA:-$HOME/AppData/Roaming}")"
    CLAUDE_CONFIG="$APPDATA_UNIX/Claude/claude_desktop_config.json"
    CURSOR_CONFIG="$HOME/.cursor/mcp.json"
    ;;
  *)
    echo -e "${YELLOW}Unknown OS. Using Unix-style config paths.${NC}"
    CLAUDE_CONFIG="$HOME/.config/Claude/claude_desktop_config.json"
    CURSOR_CONFIG="$HOME/.cursor/mcp.json"
    ;;
esac

INSTALLED_CLAUDE=false
INSTALLED_CURSOR=false

if $SETUP_CLAUDE; then
  echo -e "${BLUE}Configuring Claude Desktop...${NC}"
  if ! command -v npx >/dev/null 2>&1; then
    echo -e "${YELLOW}  npx was not found. Claude Desktop needs Node.js because it uses mcp-remote as a local bridge.${NC}"
    echo -e "${YELLOW}  Install Node.js from https://nodejs.org, then restart Claude Desktop after setup.${NC}"
  fi
  if write_config "$CLAUDE_CONFIG" "claude" "Claude Desktop"; then
    INSTALLED_CLAUDE=true
  fi
  echo ""
fi

if $SETUP_CURSOR; then
  echo -e "${BLUE}Configuring Cursor...${NC}"
  if write_config "$CURSOR_CONFIG" "cursor" "Cursor"; then
    INSTALLED_CURSOR=true
  fi
  echo ""
fi

echo -e "${BLUE}════════════════════════════════════════════${NC}"
echo ""

if $INSTALLED_CLAUDE || $INSTALLED_CURSOR; then
  echo -e "${GREEN}Setup complete!${NC}"
  echo ""

  if $INSTALLED_CLAUDE; then
    echo -e "  ${GREEN}✓${NC} Claude Desktop configured with mcp-remote"
  fi
  if $INSTALLED_CURSOR; then
    echo -e "  ${GREEN}✓${NC} Cursor configured with Streamable HTTP"
  fi

  echo ""
  echo -e "${BLUE}Next steps:${NC}"
  echo "  1. Restart Claude Desktop and/or Cursor"
  echo "  2. Generate your API token at https://www.mybrag.app/dashboard/settings"
  echo "  3. Ask your assistant to call mybrag_verify_token with your token"
  echo "  4. Use mybrag_add_entry to log accomplishments"
  echo ""
  echo -e "${YELLOW}Example:${NC}"
  echo '  "Log my accomplishment: I shipped the new auth system today"'
  echo ""
else
  echo -e "${RED}Setup did not complete.${NC}"
  echo ""
  echo "Manual Cursor config:"
  cat <<EOF
{
  "mcpServers": {
    "mybrag": {
      "type": "http",
      "url": "$MCP_URL"
    }
  }
}
EOF
  echo ""
  echo "Manual Claude Desktop config:"
  cat <<EOF
{
  "mcpServers": {
    "mybrag": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "$MCP_URL"]
    }
  }
}
EOF
fi
