#!/bin/bash
#
# Cmd+Ctrl Installation Script
# Run with: curl -fsSL https://docs.cmd-ctrl.ai/install.sh | bash
#

set -e

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

# Branding
BRAND="Cmd+Ctrl"
SERVER_URL="https://api.cmd-ctrl.ai"

# State
SELECTED_AGENTS=()
INSTALLED_AGENTS=()

#######################################
# Helper Functions
#######################################

print_banner() {
    local CMD='\033[38;2;0;255;65m'   # Phosphor green (#00FF41) – Cmd
    local PLUS='\033[38;2;40;176;40m' # Brand green (#28B028) – +
    local CTRL='\033[97m'             # White – Ctrl
    echo ""
    echo -e "${PLUS}    ${NC}${CMD}▄▄▄         ▄ ${NC}${PLUS}    ${NC}${CTRL}▄▄▄         ▄${NC}"
    echo -e "${PLUS}▀▄  ${NC}${CMD}█░▀ ▄▄▄▄▄ ▄▄█ ${NC}${PLUS} ▄  ${NC}${CTRL}█░▀ ▄█▄ █▄▄ █${NC}"
    echo -e "${PLUS} ▄▀ ${NC}${CMD}█ ▄ █░█░█ █░█ ${NC}${PLUS}▀█▀ ${NC}${CTRL}█ ▄ ░█░ █░▀ █${NC}"
    echo -e "${PLUS}▀   ${NC}${CMD}▀▀▀ ▀   ▀ ▀▀▀ ${NC}${PLUS}    ${NC}${CTRL}▀▀▀  ▀▀ ▀   ▀${NC}"
    echo "    Control your AI coding agents from anywhere."
    echo ""
}

print_step() {
    echo -e "\n${BLUE}${BOLD}▸ $1${NC}"
}

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

print_warning() {
    echo -e "${YELLOW}⚠ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

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

confirm() {
    local prompt="$1"
    local default="${2:-y}"

    if [[ "$default" == "y" ]]; then
        prompt="$prompt [Y/n] "
    else
        prompt="$prompt [y/N] "
    fi

    read -r -p "$prompt" response </dev/tty
    response=${response:-$default}

    [[ "$response" =~ ^[Yy]$ ]]
}

check_command() {
    command -v "$1" &> /dev/null
}

#######################################
# Prerequisite Checks
#######################################

check_prerequisites() {
    print_step "Checking prerequisites..."

    local missing=()

    # Check for Node.js
    if check_command node; then
        local node_version=$(node -v | sed 's/v//' | cut -d. -f1)
        if [[ "$node_version" -ge 18 ]]; then
            print_success "Node.js $(node -v) found"
        else
            print_warning "Node.js $(node -v) found, but 18+ recommended"
        fi
    else
        missing+=("Node.js 18+")
    fi

    # Check for npm
    if check_command npm; then
        print_success "npm $(npm -v) found"
    else
        missing+=("npm")
    fi

    if [[ ${#missing[@]} -gt 0 ]]; then
        print_error "Missing prerequisites:"
        for item in "${missing[@]}"; do
            echo "  - $item"
        done
        echo ""
        echo "Please install the missing prerequisites and run this script again."
        echo "Node.js: https://nodejs.org/"
        exit 1
    fi

    print_success "All prerequisites met!"
}

#######################################
# Agent Selection
#######################################

show_agent_menu() {
    print_step "Select your coding agents"
    echo ""
    echo "Which AI coding agents do you want Cmd+Ctrl to connect to?"
    echo ""
    echo -e "  ${BOLD}1)${NC} Claude Code      - Anthropic's Claude in your terminal"
    echo -e "  ${BOLD}2)${NC} Gemini CLI       - Google's Gemini in your terminal"
    echo -e "  ${BOLD}3)${NC} Codex CLI        - OpenAI's Codex in your terminal"
    echo -e "  ${BOLD}4)${NC} Cursor CLI       - Cursor's AI agent in your terminal"
    echo -e "  ${BOLD}5)${NC} Copilot CLI      - GitHub Copilot in your terminal"
    echo -e "  ${BOLD}6)${NC} OpenCode         - Open source AI coding agent"
    echo -e "  ${BOLD}7)${NC} Aider            - AI pair programming in terminal"
    echo -e "  ${BOLD}8)${NC} OpenClaw         - Personal AI assistant gateway"
    echo -e "  ${BOLD}9)${NC} Pi               - BYOM coding agent (@mariozechner/pi-coding-agent)"
    echo -e "  ${BOLD}10)${NC} Cursor IDE      ${YELLOW}[Beta]${NC} - AI-powered code editor"
    echo -e "  ${BOLD}11)${NC} GitHub Copilot  ${YELLOW}[Beta]${NC} - VS Code with Copilot"
    echo ""

    read -r -p "Enter your choices (e.g., for Claude Code and Codex CLI, just type: 1 3): " choices </dev/tty

    SELECTED_AGENTS=()
    for choice in $choices; do
        case $choice in
            1) SELECTED_AGENTS+=("claude-code") ;;
            2) SELECTED_AGENTS+=("gemini-cli") ;;
            3) SELECTED_AGENTS+=("codex-cli") ;;
            4) SELECTED_AGENTS+=("cursor-cli") ;;
            5) SELECTED_AGENTS+=("copilot-cli") ;;
            6) SELECTED_AGENTS+=("opencode") ;;
            7) SELECTED_AGENTS+=("aider") ;;
            8) SELECTED_AGENTS+=("openclaw") ;;
            9) SELECTED_AGENTS+=("pi") ;;
            10) SELECTED_AGENTS+=("cursor-ide") ;;
            11) SELECTED_AGENTS+=("vscode-copilot") ;;
            *) print_warning "Invalid choice: $choice (skipped)" ;;
        esac
    done

    if [[ ${#SELECTED_AGENTS[@]} -eq 0 ]]; then
        print_error "No agents selected. Please select at least one agent."
        show_agent_menu
    fi
}

#######################################
# Agent Prerequisites
#######################################

check_agent_prerequisites() {
    local agent="$1"

    case $agent in
        claude-code)
            if check_command claude; then
                print_success "Claude Code CLI found"
                return 0
            else
                print_warning "Claude Code CLI not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/claude-code"
                echo ""
                if confirm "Continue anyway? You can install Claude Code later."; then
                    return 0
                fi
                return 1
            fi
            ;;
        cursor-ide)
            if [[ -d "/Applications/Cursor.app" ]] || check_command cursor; then
                print_success "Cursor IDE found"
                print_info "Note: Cursor must be launched with --remote-debugging-port=9222"
                return 0
            else
                print_warning "Cursor IDE not detected"
                echo ""
                echo "  Download from: https://cursor.com"
                echo "  If Cursor is installed in a custom location, you can safely continue."
                echo ""
                if confirm "Continue anyway?"; then
                    return 0
                fi
                return 1
            fi
            ;;
        vscode-copilot)
            if check_command code; then
                print_success "VS Code found"
                print_info "Ensure GitHub Copilot extension is installed"
                print_info "Note: VS Code must be launched with --remote-debugging-port=9223"
                return 0
            else
                print_warning "VS Code not detected"
                echo ""
                echo "  Download from: https://code.visualstudio.com"
                echo "  If VS Code is installed but 'code' is not in your PATH, you can safely continue."
                echo ""
                if confirm "Continue anyway?"; then
                    return 0
                fi
                return 1
            fi
            ;;
        aider)
            local missing=()

            if ! check_command python3 && ! check_command python; then
                missing+=("Python 3.8+")
            else
                print_success "Python found"
            fi

            if ! check_command aider; then
                missing+=("aider")
            else
                print_success "Aider found"
            fi

            if ! check_command agentapi; then
                missing+=("agentapi")
            else
                print_success "AgentAPI found"
            fi

            if [[ ${#missing[@]} -gt 0 ]]; then
                print_warning "Missing for Aider:"
                for item in "${missing[@]}"; do
                    echo "    - $item"
                done
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/aider"
                echo ""
                if confirm "Continue anyway? You can install these later."; then
                    return 0
                fi
                return 1
            fi
            return 0
            ;;
        gemini-cli)
            if check_command gemini; then
                print_success "Gemini CLI found"
                return 0
            else
                print_warning "Gemini CLI not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/gemini-cli"
                echo ""
                if confirm "Continue anyway? You can install Gemini CLI later."; then
                    return 0
                fi
                return 1
            fi
            ;;
        codex-cli)
            if check_command codex; then
                print_success "Codex CLI found"
                return 0
            else
                print_warning "Codex CLI not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/codex-cli"
                echo ""
                if confirm "Continue anyway? You can install Codex CLI later."; then
                    return 0
                fi
                return 1
            fi
            ;;
        cursor-cli)
            if check_command cursor-agent; then
                print_success "Cursor CLI (cursor-agent) found"
                return 0
            else
                print_warning "Cursor CLI (cursor-agent) not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/cursor-cli"
                echo ""
                if confirm "Continue anyway? You can install cursor-agent later."; then
                    return 0
                fi
                return 1
            fi
            ;;
        copilot-cli)
            if check_command copilot; then
                print_success "GitHub Copilot CLI found"
                return 0
            else
                print_warning "GitHub Copilot CLI not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/copilot-cli"
                echo ""
                if confirm "Continue anyway? You can install Copilot CLI later."; then
                    return 0
                fi
                return 1
            fi
            ;;
        opencode)
            if check_command opencode; then
                print_success "OpenCode found"
                return 0
            else
                print_warning "OpenCode not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/opencode"
                echo ""
                if confirm "Continue anyway? You can install OpenCode later."; then
                    return 0
                fi
                return 1
            fi
            ;;
        openclaw)
            if check_command openclaw; then
                print_success "OpenClaw found"
                return 0
            else
                print_warning "OpenClaw not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/openclaw"
                echo ""
                if confirm "Continue anyway? You can install OpenClaw later."; then
                    return 0
                fi
                return 1
            fi
            ;;
        pi)
            if check_command pi; then
                print_success "Pi CLI found"
                return 0
            else
                print_warning "Pi CLI not found"
                echo ""
                echo "  Setup instructions: https://docs.cmd-ctrl.ai/installation/pi"
                echo ""
                if confirm "Continue anyway? You can install pi later."; then
                    return 0
                fi
                return 1
            fi
            ;;
    esac
}

#######################################
# Installation
#######################################

get_package_name() {
    local agent="$1"
    echo "@cmdctrl/$agent"
}

install_daemon() {
    local agent="$1"
    local package_name=$(get_package_name "$agent")
    local cli_name="cmdctrl-$agent"

    print_step "Checking $package_name..."

    # Check if already installed (use npm list to avoid CLI debug output)
    local installed_version=$(npm list -g "$package_name" --depth=0 2>/dev/null | grep "$package_name" | sed 's/.*@//' || echo "")
    if [[ -n "$installed_version" ]]; then
        local latest_version=$(npm view "$package_name" version 2>/dev/null || echo "unknown")

        if [[ "$installed_version" == "$latest_version" ]]; then
            print_success "$package_name@$installed_version is up to date"
            INSTALLED_AGENTS+=("$agent")
            return 0
        elif [[ "$latest_version" != "unknown" ]]; then
            print_warning "$package_name@$installed_version installed, $latest_version available"
            if confirm "Update to latest version?"; then
                print_info "Updating $package_name..."
            else
                print_info "Keeping current version"
                INSTALLED_AGENTS+=("$agent")
                return 0
            fi
        else
            print_success "$package_name@$installed_version already installed"
            INSTALLED_AGENTS+=("$agent")
            return 0
        fi
    else
        print_info "Installing $package_name..."
    fi

    if npm install -g "$package_name" 2>/dev/null; then
        print_success "Installed $package_name"
        INSTALLED_AGENTS+=("$agent")
        return 0
    else
        print_error "Failed to install $package_name"
        echo ""
        echo "Try running manually with sudo:"
        echo "  sudo npm install -g $package_name"
        echo ""
        return 1
    fi
}

#######################################
# Registration
#######################################

register_daemon() {
    local agent="$1"
    local cli_name="cmdctrl-$agent"
    local config_file="$HOME/.cmdctrl-$agent/config.json"

    print_step "Registering $cli_name with ${BRAND}..."

    # Check if already registered
    local skip_confirm=false
    if [[ -f "$config_file" ]]; then
        local current_server=$(cat "$config_file" 2>/dev/null | grep -o '"serverUrl"[^,}]*' | cut -d'"' -f4)
        print_warning "Already registered"
        if [[ -n "$current_server" ]]; then
            echo "  Current server: $current_server"
        fi
        echo ""
        if ! confirm "Unregister and re-register to ${SERVER_URL}?"; then
            print_info "Keeping existing registration"
            return 0
        fi
        echo ""
        print_info "Removing existing registration..."
        # Stop and remove any existing service
        if [[ "$OSTYPE" == "darwin"* ]]; then
            local plist_file="$HOME/Library/LaunchAgents/ai.cmd-ctrl.$agent.plist"
            if [[ -f "$plist_file" ]]; then
                launchctl unload "$plist_file" 2>/dev/null
                rm -f "$plist_file"
            fi
        elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
            systemctl --user stop "cmdctrl-$agent" 2>/dev/null
            systemctl --user disable "cmdctrl-$agent" 2>/dev/null
            rm -f "$HOME/.config/systemd/user/cmdctrl-$agent.service"
        fi
        # Stop any running daemon process
        $cli_name stop 2>/dev/null
        rm -f "$config_file" "$HOME/.cmdctrl-$agent/credentials" 2>/dev/null
        skip_confirm=true
    fi

    if [[ "$skip_confirm" == false ]]; then
        echo ""
        if ! confirm "Ready to register with ${SERVER_URL}?"; then
            print_warning "Skipping registration for $cli_name"
            echo "  You can register later with: $cli_name register -s $SERVER_URL"
            return 0
        fi
    fi

    if $cli_name register -s "$SERVER_URL"; then
        print_success "Registered $cli_name!"
        return 0
    else
        print_error "Registration failed for $cli_name"
        echo "  Try again later with: $cli_name register -s $SERVER_URL"
        return 1
    fi
}

#######################################
# Service Setup
#######################################

start_daemon() {
    local agent="$1"
    local cli_name="cmdctrl-$agent"
    local log_file="/tmp/cmdctrl-$agent.log"

    echo ""
    print_info "Starting $cli_name..."

    # Run in background, redirect output to log file
    nohup $cli_name start > "$log_file" 2>&1 &
    sleep 2  # Give it time to start

    # Check if it's running
    if pgrep -f "$cli_name" > /dev/null 2>&1; then
        print_success "$cli_name is now running"
        echo ""
        echo "  Log file: $log_file"
        echo ""
        echo "  Note: You'll need to restart it after reboot."
        echo "  For auto-start setup, see: https://docs.cmd-ctrl.ai/installation/#auto-start"
    else
        print_warning "Could not start $cli_name"
        echo "  Check log: $log_file"
        echo "  Start manually with: $cli_name start"
    fi
}

#######################################
# Agent-specific setup hints
#######################################

show_agent_hints() {
    local agent="$1"

    case $agent in
        cursor-ide)
            echo ""
            print_info "Cursor IDE Setup:"
            echo "  Cursor must be launched with a special flag:"
            echo ""
            echo "    /Applications/Cursor.app/Contents/MacOS/Cursor --remote-debugging-port=9222"
            echo ""
            echo "  Add this alias to your shell profile for convenience:"
            echo "    alias cursor='/Applications/Cursor.app/Contents/MacOS/Cursor --remote-debugging-port=9222'"
            echo ""
            ;;
        vscode-copilot)
            echo ""
            print_info "VS Code Setup:"
            echo "  VS Code must be launched with a special flag:"
            echo ""
            echo "    code --remote-debugging-port=9223"
            echo ""
            echo "  Add this alias to your shell profile for convenience:"
            echo "    alias code='code --remote-debugging-port=9223'"
            echo ""
            ;;
    esac
}

#######################################
# Completion
#######################################

show_completion() {
    echo ""
    echo -e "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}${BOLD}  ✓ Installation Complete!${NC}"
    echo -e "${GREEN}${BOLD}════════════════════════════════════════════════════════════${NC}"
    echo ""
    echo -e "${BOLD}${CYAN}▶ NEXT STEP: Interact with your agent${NC}"
    echo ""
    echo -e "  Web:    ${BOLD}https://app.cmd-ctrl.ai/dashboard${NC}"
    echo -e "  Mobile: Open the Cmd+Ctrl app to start or connect to a session"
    echo ""

    for agent in "${INSTALLED_AGENTS[@]}"; do
        show_agent_hints "$agent"
    done

    echo -e "${BOLD}Need Help?${NC}"
    echo "  Docs: https://docs.cmd-ctrl.ai/"
    echo ""
}

#######################################
# Main
#######################################

main() {
    print_banner

    # Check prerequisites
    check_prerequisites

    # Select agents
    show_agent_menu

    echo ""
    echo "You selected: ${SELECTED_AGENTS[*]}"
    echo ""

    # Check agent-specific prerequisites
    print_step "Checking agent prerequisites..."
    local agents_to_install=()
    for agent in "${SELECTED_AGENTS[@]}"; do
        if check_agent_prerequisites "$agent"; then
            agents_to_install+=("$agent")
        fi
    done

    if [[ ${#agents_to_install[@]} -eq 0 ]]; then
        print_error "No agents to install. Please resolve prerequisites and try again."
        exit 1
    fi

    # Install daemons
    for agent in "${agents_to_install[@]}"; do
        install_daemon "$agent"
    done

    if [[ ${#INSTALLED_AGENTS[@]} -eq 0 ]]; then
        print_error "No daemons were installed successfully."
        exit 1
    fi

    # Register daemons
    for agent in "${INSTALLED_AGENTS[@]}"; do
        register_daemon "$agent"
    done

    # Start daemons
    for agent in "${INSTALLED_AGENTS[@]}"; do
        start_daemon "$agent"
    done

    # Show completion
    show_completion
}

# Run main
main "$@"
