#!/usr/bin/env bash
# ============================================================
# OpenIT — One-Command Install
# Gets you to your first working ticket in under 10 minutes.
# Mac + Windows (WSL/bash), no server needed.
# ============================================================

set -e

# ── Colours & UI helpers ────────────────────────────────────
RED='\n\ufb58'
GREEN='\u001b[32m'
YELLOW='\u001b[33m'
BOLD='\u001b[1m'
RESET='\u001b[0m'

info()    { echo -e "${GREEN}[openit]${RESET}  $1"; }
warn()    { echo -e "${YELLOW}[openit]${RESET}  $1"; }
error()   { echo -e "${RED}[openit]${RESET}  $1"; }
section() { echo -e "\n${BOLD}━━ $1 ━━${RESET}"; }

# ── Detect OS ────────────────────────────────────────────────
detect_os() {
  if [[ "$OSTYPE" == "darwin"* ]]; then
    echo "macos"
  elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" || -n "$WSL_DISTRO_NAME" ]]; then
    echo "windows"
  elif command -v cygpath &>/dev/null; then
    echo "windows"
  else
    echo "linux"
  fi
}

OS=$(detect_os)
info "Detected OS: $OS"

# ── Detect Node ───────────────────────────────────────────────
if ! command -v node &>/dev/null; then
  section "Installing Node.js"
  if [[ "$OS" == "macos" ]]; then
    if command -v brew &>/dev/null; then
      info "Installing Node.js via Homebrew..."
      brew install node
    else
      error "Node.js not found. Install from https://nodejs.org or run: brew install node"
      exit 1
    fi
  elif [[ "$OS" == "windows" || "$OS" == "linux" ]]; then
    info "Installing Node.js via nvm (recommended)..."
    export NVM_DIR="$HOME/.nvm"
    if [[ ! -d "$NVM_DIR" ]]; then
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
    fi
    [ -s "$NVM_DIR/nvm.sh" ] && \nnvm source "$NVM_DIR/nvm.sh"
    nvm install 20 --lts
    nvm use 20
  fi
fi

info "Node version: $(node -v)"
info "npm version: $(npm -v)"

# ── Locate / create vault directory ──────────────────────────
VAULT_DIR="${OPENIT_VAULT:-$HOME/openit-vault}"
OPENIT_PORT="${OPENIT_PORT:-3000}"

section "Setting up vault at $VAULT_DIR"
if [[ -d "$VAULT_DIR" ]]; then
  info "Vault already exists — skipping clone."
else
  info "Cloning skills vault template..."
  mkdir -p "$VAULT_DIR"
  # Create the standard skill vault structure
  mkdir -p "$VAULT_DIR/skills"
  mkdir -p "$VAULT_DIR/scripts"
  mkdir -p "$VAULT_DIR/kb"

  # Write the example skills
  cat > "$VAULT_DIR/README.md" << 'VAULT_README'
# OpenIT Skills Vault

This is your OpenIT vault. Skills are plain Markdown files that Claude reads
to handle IT requests autonomously.

## Directory structure

```
skills/     — Skill files (see below)
scripts/    — Helper scripts Claude can run
kb/         — Auto-generated knowledge base articles
```

## How skills work

A skill file is a Markdown file with:

1. **Title** — first H1 heading
2. **Trigger** — words/phrases that activate this skill
3. **Steps** — what Claude should do
4. **Response template** — what Claude says when applied

## Example skill

# Reset VPN access

Triggers: vpn not working, can't connect to vpn, vpn error, reset vpn
Steps: Run `openvpn kill && brew services restart openvpn`, then verify DNS
Response: "VPN has been reset. Try connecting again — let me know if it works."

## Adding your first skill

Open the wizard at http://localhost:3000/setup after starting OpenIT.
VAULT_README

  # Create example starter skills
  cat > "$VAULT_DIR/skills/00-template.md" << 'SKILL_TEMPLATE'
# [Skill Name]

Triggers: trigger phrase 1, trigger phrase 2, trigger phrase 3
Context: Who this applies to and when to use this skill
Steps:
1. Step one
2. Step two
3. Step three
Response: "Done! [brief confirmation message]"
SKILL_TEMPLATE

  info "Vault created at $VAULT_DIR"
fi

# ── Check for existing .env ───────────────────────────────────
ENV_FILE="$VAULT_DIR/.env"
if [[ -f "$ENV_FILE" ]]; then
  info "Found existing .env — will update it."
  source "$ENV_FILE"
fi

# ── Configure Slack bot (Socket Mode) ────────────────────────
section "Configuring Slack bot (Socket Mode)"

# Check if Slack tokens are already configured
if [[ -z "$SLACK_APP_TOKEN" || "$SLACK_APP_TOKEN" == "your_slack_app_token_here" ]]; then
  echo ""
  echo -e "  ${BOLD}Need your Slack bot credentials.${RESET}"
  echo "  Create a Slack app at https://api.slack.com/apps"
  echo "  Enable Socket Mode, then copy:"
  echo ""

  read -p "  Slack App Token (xapp-...): " SLACK_APP_TOKEN
  read -p "  Slack Bot Token (xoxb-...): " SLACK_BOT_TOKEN
  read -p "  Default channel for #it-help (e.g. #it): " SLACK_CHANNEL
else
  info "Slack already configured — skipping."
fi

# ── Check / configure OpenAI key ─────────────────────────────
section "Configuring AI"

if [[ -z "$OPENAI_API_KEY" || "$OPENAI_API_KEY" == "your_openai_key_here" ]]; then
  echo ""
  echo -e "  ${BOLD}OpenAI API key needed for AI ticket responses.${RESET}"
  read -p "  OpenAI API Key (sk-...): " OPENAI_API_KEY
else
  info "OpenAI key already configured."
fi

# ── Write .env file ───────────────────────────────────────────
section "Writing configuration"

cat > "$ENV_FILE" << ENV_EOF
# OpenIT Configuration — generated by install.sh on $(date)
OPENIT_VAULT=$VAULT_DIR
OPENIT_PORT=$OPENIT_PORT

# Slack (Socket Mode)
SLACK_APP_TOKEN=${SLACK_APP_TOKEN:-}
SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN:-}
SLACK_CHANNEL=${SLACK_CHANNEL:-#it}

# OpenAI
OPENAI_API_KEY=${OPENAI_API_KEY:-}

# Database — for production use Render+Neon (DATABASE_URL set by Polsia infra).
# For local dev, set DATABASE_URL to your Postgres connection string.
DATABASE_URL=${DATABASE_URL:-}

# Setup wizard
OPENIT_SETUP_COMPLETED=false
ENV_EOF

info "Config written to $ENV_FILE"

# ── Install dependencies ─────────────────────────────────────
section "Installing OpenIT"

INSTALL_DIR="$VAULT_DIR/server"
if [[ ! -d "$INSTALL_DIR/node_modules" ]]; then
  info "Installing Node.js dependencies..."
  npm install --prefix "$INSTALL_DIR" express ejs pg openai @slack/web-api @slack/socket-mode 2>/dev/null || npm install --prefix "$INSTALL_DIR" express ejs pg openai 2>/dev/null
  info "Dependencies installed."
fi

# Copy server files if not already there
if [[ ! -f "$INSTALL_DIR/server.js" ]]; then
  SCRIPT_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)"
  if [[ -f "$SCRIPT_DIR/server.js" ]]; then
    info "Copying server files from: $SCRIPT_DIR"
    cp "$SCRIPT_DIR/server.js" "$SCRIPT_DIR/package.json" "$INSTALL_DIR/" 2>/dev/null || true
    cp -r "$SCRIPT_DIR/routes" "$SCRIPT_DIR/db" "$SCRIPT_DIR/views" "$SCRIPT_DIR/public" "$SCRIPT_DIR/lib" "$SCRIPT_DIR/migrations" "$INSTALL_DIR/" 2>/dev/null || true
  fi
fi

# ── Start the server ─────────────────────────────────────────
section "Starting OpenIT server"

cd "$INSTALL_DIR"

# Check if port is in use
if lsof -Pi :$OPENIT_PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
  info "Port $OPENIT_PORT already in use — OpenIT is already running."
else
  info "Starting server on port $OPENIT_PORT..."

  # Try to start in background, fall back to foreground if bg fails
  if command -v nohup >/dev/null 2>&1; then
    nohup node server.js > "$VAULT_DIR/openit.log" 2>&1 &
    SERVER_PID=$!
    info "Server started (PID: $SERVER_PID)"
    sleep 2
  else
    node server.js &
    SERVER_PID=$!
    info "Server started in background (PID: $SERVER_PID)"
    sleep 2
  fi

  # Verify server is up
  if curl -sf "http://localhost:$OPENIT_PORT/health" >/dev/null 2>&1; then
    info "Server is running!"
  else
    warn "Server may not be fully started yet — checking logs..."
    cat "$VAULT_DIR/openit.log" 2>/dev/null || echo "(no log file yet)"
  fi
fi

# ── Run the skill setup wizard ────────────────────────────────
section "Skill Setup Wizard"

echo ""
echo -e "  ${BOLD}What's your most common IT request?${RESET}"
echo "  This becomes your first skill. OpenIT will handle it automatically."
echo ""
echo -e "  ${YELLOW}Open this URL in your browser:${RESET}"
echo -e "  ${GREEN}  → http://localhost:$OPENIT_PORT/setup${RESET}"
echo ""

# Open browser
if [[ "$OS" == "macos" ]]; then
  open "http://localhost:$OPENIT_PORT/setup" 2>/dev/null || true
elif [[ "$OS" == "windows" ]]; then
  start "http://localhost:$OPENIT_PORT/setup" 2>/dev/null || true
fi

info "Complete the wizard in your browser, then return here."

# Poll for wizard completion (15 second timeout)
info "Waiting for setup to complete..."
ATTEMPTS=0
while [[ $ATTEMPTS -lt 30 ]]; do
  sleep 1
  SETUP_STATUS=$(curl -sf "http://localhost:$OPENIT_PORT/api/setup/status" 2>/dev/null | grep -o '"completed":true' || echo "")
  if [[ -n "$SETUP_STATUS" ]]; then
    break
  fi
  ATTEMPTS=$((ATTEMPTS + 1))

  # Show spinner
  if [[ $((ATTEMPTS % 5)) -eq 0 ]]; then
    echo -n "."
  fi
done
echo ""

if [[ -n "$SETUP_STATUS" ]]; then
  info "Setup complete! First skill created."
else
  warn "Wizard not completed in time. You can still complete it at:"
  echo "  http://localhost:$OPENIT_PORT/setup"
fi

# ── Final summary ─────────────────────────────────────────────
section "Done!"

echo ""
echo -e "  ${GREEN}${BOLD}OpenIT is ready.${RESET}"
echo ""
echo -e "  ${BOLD}Your vault:${RESET}     $VAULT_DIR"
echo -e "  ${BOLD}App URL:${RESET}        http://localhost:$OPENIT_PORT"
echo -e "  ${BOLD}Setup wizard:${RESET}   http://localhost:$OPENIT_PORT/setup"
echo ""
echo -e "  Next: Invite the Slack bot to your #it-help channel."
echo ""
echo -e "  ${BOLD}To stop:${RESET}  kill \\\\$(cat $VAULT_DIR/.pid 2>/dev/null) 2>/dev/null || pkill -f 'node.*openit'"
echo -e "  ${BOLD}To start:${RESET} cd $INSTALL_DIR && node server.js"
echo ""