#!/usr/bin/env bash
# ═══════════════════════════════════════════════════════════════════════════
#  mona-start.sh – Enterprise macOS Terminal App for mona.expert
#  ═══════════════════════════════════════════════════════════════════════════
#  Purpose:
#    1) Verify system prerequisites (Node.js ≥18, git, openssl, etc.)
#    2) Generate mTLS client certificates if missing
#    3) Authenticate mona-sync to the remote mona.expert SaaS backend
#    4) Start the local wrapper (server.js) and website-server.js
#    5) Open the enterprise dashboard in your browser
#  ═══════════════════════════════════════════════════════════════════════════
#  Usage:
#    chmod +x mona-start.sh && ./mona-start.sh
#    ./mona-start.sh --quick   skip cert generation if already done
#    ./mona-start.sh --help    detailed help
#  ═══════════════════════════════════════════════════════════════════════════

set -euo pipefail

# ── Color output ──────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
PURPLE='\033[0;35m'
BOLD='\033[1m'
NC='\033[0m'

MONA_ROOT="${MONA_ROOT:-$HOME/Documents/mona.expert}"
MONA_SAAS="${MONA_ROOT}/website/public"         # <- static site (official path)
# Alternative: if you deploy the saas version separately:
MONA_SAAS_FALLBACK="$HOME/Documents/mona.web.saas"

WEBSITE_PORT="${WEBSITE_PORT:-4188}"
WRAPPER_PORT="${WRAPPER_PORT:-4189}"
MONA_HOST="localhost"

CERT_DIR="${MONA_ROOT}/certs"
WEBSITE_JS="${MONA_ROOT}/website-server.js"
WRAPPER_JS="${MONA_ROOT}/server.js"
MONA_SYNC="${MONA_ROOT}/mona-sync.cjs"
MONA_SYNC_CONFIG="${MONA_ROOT}/mona-sync.config.json"

# ── Helper functions ──────────────────────────────────────────────────────

log_info()  { echo -e "${CYAN}🔹${NC} $1"; }
log_ok()    { echo -e "${GREEN}✅${NC} $1"; }
log_warn()  { echo -e "${YELLOW}⚠️${NC} $1"; }
log_error() { echo -e "${RED}❌${NC} $1"; }
log_step()  { echo -e "\n${PURPLE}═══════════════════════════════════════════════${NC}"; echo -e "${BOLD}$1${NC}"; echo -e "${PURPLE}═══════════════════════════════════════════════${NC}"; }

spinner() {
  local pid=$1; local delay=0.1; local spinstr='|/-\'
  while ps -p "$pid" > /dev/null 2>&1; do
    local temp=${spinstr#?}
    printf " [%c]  " "$spinstr"
    local spinstr=$temp${spinstr%"$temp"}
    sleep $delay
    printf "\b\b\b\b\b\b"
  done
  printf "    \b\b\b\b"
}

# ── Title screen ──────────────────────────────────────────────────────────

clear
cat << "EOF"
╔══════════════════════════════════════════════════════════════╗
║                                                              ║
║   ███╗   ███╗ ██████╗ ███╗   ██╗ █████╗                     ║
║   ████╗ ████║██╔═══██╗████╗  ██║██╔══██╗                    ║
║   ██╔████╔██║██║   ██║██╔██╗ ██║███████║                    ║
║   ██║╚██╔╝██║██║   ██║██║╚██╗██║██╔══██║                    ║
║   ██║ ╚═╝ ██║╚██████╔╝██║ ╚████║██║  ██║                    ║
║   ╚═╝     ╚═╝ ╚═════╝ ╚═╝  ╚═══╝╚═╝  ╚═╝                    ║
║                                                              ║
║   ╔═══╗██████╗ ██╗  ██╗██████╗ ███████╗██████╗ ████████╗   ║
║   ╚══╗║██╔══██╗╚██╗██╔╝██╔══██╗██╔════╝██╔══██╗╚══██╔══╝   ║
║    ██║██████╔╝ ╚███╔╝ ██████╔╝█████╗  ██████╔╝   ██║      ║
║    ██║██╔═══╝  ██╔██╗ ██╔══██╗██╔══╝  ██╔══██╗   ██║      ║
║    ██║██║     ██╔╝ ██╗██║  ██║███████╗██║  ██║   ██║      ║
║   ╚═╝╚═╝     ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝   ╚═╝      ║
║                                                              ║
║   🔒 Enterprise Agent Wrapper – Terminal Setup v2.0          ║
║                                                              ║
╚══════════════════════════════════════════════════════════════╝
EOF

echo -e "\n${BOLD}📋 Prüfe Systemvoraussetzungen …${NC}\n"

# ── Step 1: Prerequisite checks ───────────────────────────────────────────

PREREQ_OK=true

# Node.js
if command -v node &>/dev/null; then
  NODE_VER=$(node -v 2>/dev/null | sed 's/v//' | cut -d. -f1)
  if [ "$NODE_VER" -ge 18 ] 2>/dev/null; then
    log_ok "Node.js $(node -v) detected"
  else
    log_warn "Node.js $(node -v) – minimum 18+ recommended"
  fi
else
  log_error "Node.js not found. Install from https://nodejs.org"
  PREREQ_OK=false
fi

# npm
if command -v npm &>/dev/null; then
  log_ok "npm $(npm -v) detected"
else
  log_error "npm not found"
  PREREQ_OK=false
fi

# OpenSSL
if command -v openssl &>/dev/null; then
  log_ok "OpenSSL $(openssl version | awk '{print $1, $2}') detected"
else
  log_error "OpenSSL not found. Install via: xcode-select --install"
  PREREQ_OK=false
fi

# Git
if command -v git &>/dev/null; then
  log_ok "Git $(git --version | awk '{print $3}') detected"
else
  log_warn "Git not found – not critical, but recommended"
fi

# Check project directory
if [ ! -f "$WRAPPER_JS" ]; then
  log_warn "server.js not found at $WRAPPER_JS"
  log_info "Looking for mona.expert project…"
  if [ -d "$HOME/Documents/mona.expert" ]; then
    MONA_ROOT="$HOME/Documents/mona.expert"
    WEBSITE_JS="${MONA_ROOT}/website-server.js"
    WRAPPER_JS="${MONA_ROOT}/server.js"
    MONA_SYNC="${MONA_ROOT}/mona-sync.cjs"
    CERT_DIR="${MONA_ROOT}/certs"
    MONA_SYNC_CONFIG="${MONA_ROOT}/mona-sync.config.json"
    log_ok "Found mona.expert at $MONA_ROOT"
  else
    log_error "mona.expert project not found!"
    log_info "Clone it: git clone https://github.com/mona-experts/mona.expert.git ~/Documents/mona.expert"
    PREREQ_OK=false
  fi
fi

# npm dependencies
if [ -f "${MONA_ROOT}/package.json" ] && [ -d "${MONA_ROOT}/node_modules" ]; then
  log_ok "npm dependencies installed"
elif [ -f "${MONA_ROOT}/package.json" ]; then
  log_warn "npm dependencies not installed – running npm install…"
  (cd "$MONA_ROOT" && npm install --production) &
  spinner $!
fi

if [ "$PREREQ_OK" = false ]; then
  log_error "Some prerequisites are missing. Please fix the issues above and re-run."
  exit 1
fi

# ── Step 2: mTLS certificates ────────────────────────────────────────────

log_step "🔐 Schritt 1/5: mTLS Client-Zertifikate prüfen"

if [ -f "${CERT_DIR}/client-cert.pem" ] && [ -f "${CERT_DIR}/client-key.pem" ]; then
  log_ok "mTLS client certificates found at $CERT_DIR"
  # Check expiration
  EXPIRY=$(openssl x509 -in "${CERT_DIR}/client-cert.pem" -noout -enddate 2>/dev/null | cut -d= -f2)
  if [ -n "$EXPIRY" ]; then
    EXP_EPOCH=$(date -j -f "%b %d %T %Y %Z" "$EXPIRY" +%s 2>/dev/null || echo 0)
    NOW_EPOCH=$(date +%s)
    if [ "$NOW_EPOCH" -gt "$EXP_EPOCH" ] 2>/dev/null; then
      log_warn "Client certificate expired on $EXPIRY – regenerating…"
      rm -f "${CERT_DIR}/client-cert.pem" "${CERT_DIR}/client-key.pem"
    else
      DAYS_LEFT=$(( (EXP_EPOCH - NOW_EPOCH) / 86400 ))
      log_info "Certificate expires in $DAYS_LEFT days ($EXPIRY)"
    fi
  fi
fi

# Generate CA and client certs if missing
if [ ! -f "${CERT_DIR}/ca-cert.pem" ]; then
  log_info "Generating CA certificate…"
  mkdir -p "$CERT_DIR"
  openssl req -x509 -new -nodes -sha256 -days 3650 \
    -subj "/CN=mona.expert CA" \
    -keyout "${CERT_DIR}/ca-key.pem" \
    -out "${CERT_DIR}/ca-cert.pem" 2>/dev/null
  log_ok "CA certificate generated"
fi

if [ ! -f "${CERT_DIR}/client-cert.pem" ]; then
  log_info "Generating client certificate (mTLS)…"
  openssl req -new -nodes -sha256 \
    -subj "/CN=mona-dashboard" \
    -keyout "${CERT_DIR}/client-key.pem" \
    -out "${CERT_DIR}/client.csr" 2>/dev/null
  openssl x509 -req -sha256 -days 365 \
    -in "${CERT_DIR}/client.csr" \
    -CA "${CERT_DIR}/ca-cert.pem" \
    -CAkey "${CERT_DIR}/ca-key.pem" \
    -CAcreateserial \
    -out "${CERT_DIR}/client-cert.pem" 2>/dev/null
  rm -f "${CERT_DIR}/client.csr"
  log_ok "Client certificate generated (valid 365 days)"
  # Set permissions
  chmod 600 "${CERT_DIR}/client-key.pem" "${CERT_DIR}/ca-key.pem"
fi

# ── Step 3: mona-sync setup ──────────────────────────────────────────────

log_step "☁️  Schritt 2/5: mona-sync – Verbindung zu mona.expert"

if [ ! -f "$MONA_SYNC" ]; then
  log_warn "mona-sync not found at $MONA_SYNC"
  log_info "Creating minimal mona-sync configuration…"
  cat > "$MONA_SYNC_CONFIG" << EOFCONF
{
  "remoteUrl": "https://mona.expert/api.php",
  "email": "",
  "password": "",
  "wrapperId": "$(hostname -s)-mona",
  "intervalSec": 30
}
EOFCONF
  log_warn "Empty config created. You need to set your credentials."
fi

# Check if sync is already configured
SYNC_EMAIL=""
if [ -f "$MONA_SYNC_CONFIG" ]; then
  SYNC_EMAIL=$(node -e "const c = require('$MONA_SYNC_CONFIG'); console.log(c.email || '')" 2>/dev/null || echo "")
fi

if [ -z "$SYNC_EMAIL" ]; then
  echo -e "\n${YELLOW}⚠️  mona-sync needs authentication credentials for the remote SaaS.${NC}"
  echo -e "${CYAN}Enter your mona.expert login credentials:${NC}"
  echo ""

  read -r -p "  Email: " SYNC_INPUT_EMAIL
  read -r -s -p "  Password: " SYNC_INPUT_PASS
  echo ""

  if [ -n "$SYNC_INPUT_EMAIL" ] && [ -n "$SYNC_INPUT_PASS" ]; then
    # Write config
    cat > "$MONA_SYNC_CONFIG" << EOFCONF2
{
  "remoteUrl": "https://mona.expert/api.php",
  "email": "$SYNC_INPUT_EMAIL",
  "password": "$SYNC_INPUT_PASS",
  "wrapperId": "$(hostname -s)-mona",
  "intervalSec": 30
}
EOFCONF2
    chmod 600 "$MONA_SYNC_CONFIG"
    log_ok "Credentials saved to $MONA_SYNC_CONFIG"

    # Test authentication
    echo -e "\n  ${CYAN}Testing authentication…${NC}"
    if command -v node &>/dev/null; then
      node -e "
        const c = require('$MONA_SYNC_CONFIG');
        const http = require('https');
        const qs = JSON.stringify({action: 'login', email: c.email, password: c.password});
        const req = https.request(new URL(c.remoteUrl), {
          method: 'POST',
          headers: {'Content-Type': 'application/json'}
        }, (res) => {
          let d = '';
          res.on('data', c => d += c);
          res.on('end', () => {
            try {
              const j = JSON.parse(d);
              if (j.status === 'ok' || j.token) process.exit(0);
              else { console.error('Auth failed:', j.message || d.substring(0,100)); process.exit(1); }
            } catch { console.error('Parse error:', d.substring(0,100)); process.exit(1); }
          });
        });
        req.on('error', e => { console.error('Connection error:', e.message); process.exit(1); });
        req.write(qs); req.end();
      " 2>&1 | (while read line; do echo "    $line"; done) && log_ok "Authentication successful" || log_warn "Auth test failed – check credentials (sync will retry)"
    fi
  else
    log_warn "Empty credentials – skipping sync setup"
  fi
else
  log_ok "mona-sync configured for $SYNC_EMAIL"
fi

# ── Step 4: Check for port conflicts ──────────────────────────────────────

log_step "🚦 Schritt 3/5: Port-Konflikte prüfen"

check_port() {
  local port=$1
  local name=$2
  if lsof -i :"$port" -P -n 2>/dev/null | grep -q LISTEN; then
    local pid=$(lsof -ti :"$port" 2>/dev/null)
    local proc_name=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
    log_warn "Port $port is already in use by PID $pid ($proc_name)"
    log_info "Attempting graceful stop…"
    kill "$pid" 2>/dev/null && sleep 1 || true
    if lsof -i :"$port" -P -n 2>/dev/null | grep -q LISTEN; then
      log_info "Force stopping PID $pid…"
      kill -9 "$pid" 2>/dev/null || true
      sleep 1
    fi
    if lsof -i :"$port" -P -n 2>/dev/null | grep -q LISTEN; then
      log_error "Could not free port $port. Please stop the process manually."
    else
      log_ok "Port $port freed"
    fi
  else
    log_ok "Port $port ($name) is available"
  fi
}

check_port "$WEBSITE_PORT" "Website-Server (Dashboard)"
check_port "$WRAPPER_PORT" "Wrapper (Internal API)"

# ── Step 5: Start services ───────────────────────────────────────────────

log_step "🚀 Schritt 4/5: Services starten"

# Cleanup function
MONA_PIDS=""
cleanup() {
  echo -e "\n${YELLOW}🛑 Shutting down mona.expert services…${NC}"
  if [ -n "$MONA_PIDS" ]; then
    kill $MONA_PIDS 2>/dev/null || true
    sleep 0.5
    # Force kill if still alive
    for pid in $MONA_PIDS; do
      kill -0 "$pid" 2>/dev/null && kill -9 "$pid" 2>/dev/null || true
    done
  fi
  log_ok "Services stopped. Goodbye."
  exit 0
}
trap cleanup SIGINT SIGTERM EXIT

cd "$MONA_ROOT"

# Start wrapper first (internal API on :4189)
log_info "Starting wrapper (port $WRAPPER_PORT)…"
if [ -f "$WRAPPER_JS" ]; then
  node "$WRAPPER_JS" &
  WRAPPER_PID=$!
  MONA_PIDS="$WRAPPER_PID"
  # Wait for wrapper to listen
  for i in $(seq 1 15); do
    if lsof -i :"$WRAPPER_PORT" -P -n 2>/dev/null | grep -q LISTEN; then
      log_ok "Wrapper running on port $WRAPPER_PORT (PID $WRAPPER_PID)"
      break
    fi
    sleep 1
  done
  if ! lsof -i :"$WRAPPER_PORT" -P -n 2>/dev/null | grep -q LISTEN; then
    log_warn "Wrapper may not have started in time (check logs)"
  fi
else
  log_warn "server.js not found – skipping wrapper start"
fi

# Start website-server (public-facing on :4188)
log_info "Starting website-server (port $WEBSITE_PORT)…"
if [ -f "$WEBSITE_JS" ]; then
  node "$WEBSITE_JS" &
  WEB_PID=$!
  MONA_PIDS="$MONA_PIDS $WEB_PID"
  for i in $(seq 1 15); do
    if lsof -i :"$WEBSITE_PORT" -P -n 2>/dev/null | grep -q LISTEN; then
      log_ok "Website-server running on port $WEBSITE_PORT (PID $WEB_PID)"
      break
    fi
    sleep 1
  done
  if ! lsof -i :"$WEBSITE_PORT" -P -n 2>/dev/null | grep -q LISTEN; then
    log_warn "Website-server may not have started in time"
  fi
else
  log_warn "website-server.js not found – skipping"
fi

# Start mona-sync (background continuous sync)
if [ -f "$MONA_SYNC" ] && [ -f "$MONA_SYNC_CONFIG" ]; then
  if node -e "const c = require('$MONA_SYNC_CONFIG'); process.exit(c.email ? 0 : 1)" 2>/dev/null; then
    log_info "Starting mona-sync (continuous mode)…"
    node "$MONA_SYNC" --watch &
    MONA_PIDS="$MONA_PIDS $!"
    sleep 1
    log_ok "mona-sync running (pushes telemetry every 30s)"
  else
    log_info "mona-sync configured but no email set – skipping continuous sync"
  fi
fi

# ── Step 6: Open dashboard ───────────────────────────────────────────────

log_step "🖥️  Schritt 5/5: Dashboard öffnen"

sleep 1

echo ""
echo -e "  ${BOLD}Your dashboard is ready:${NC}"
echo ""
echo -e "        ${GREEN}http://localhost:${WEBSITE_PORT}/dashboard.html${NC}"
echo ""
echo -e "  ${CYAN}Wrapper API:${NC}  http://localhost:${WRAPPER_PORT}/api/health"
echo -e "  ${CYAN}Status:${NC}       http://localhost:${WEBSITE_PORT}/status"
echo -e "  ${CYAN}Sync:${NC}         node $(basename "$MONA_SYNC") --watch"
echo ""
echo -e "  ${YELLOW}Press Ctrl+C to stop all services${NC}"
echo ""

# Attempt to open browser
if command -v open &>/dev/null; then
  sleep 0.5
  open "http://localhost:${WEBSITE_PORT}/dashboard.html"
  log_ok "Dashboard opened in browser"
fi

# Show live service status
echo ""
echo -e "${PURPLE}═══════════════════════════════════════════════${NC}"
echo -e "${BOLD}  ⌛ Services running – press Ctrl+C to stop${NC}"
echo -e "${PURPLE}═══════════════════════════════════════════════${NC}"
echo ""

# Wait – periodic health checks
i=0
while true; do
  sleep 5
  i=$((i + 1))
  if [ $((i % 12)) -eq 0 ]; then
    # Health check every 60s
    if command -v curl &>/dev/null; then
      WRAPPER_OK=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${WRAPPER_PORT}/api/health" 2>/dev/null || echo "000")
      WEBSITE_OK=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${WEBSITE_PORT}/" 2>/dev/null || echo "000")
      echo -e "  $(date '+%H:%M:%S') │ Wrapper: ${WRAPPER_OK} │ Website: ${WEBSITE_OK}"
    fi
  fi
done
