#!/bin/bash
# =============================================================================
# ISP Billing System - Server Setup Script
# Domain: isp.ngaredigital.com
# Run as: sudo bash setup-isp.sh
# =============================================================================
set -euo pipefail

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

log()  { echo -e "${GREEN}[SETUP]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
err()  { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
info() { echo -e "${BLUE}[INFO]${NC} $1"; }

# ---- CONFIGURATION ----
APP_DIR="/var/www/isp.ngaredigital.com"
DOMAIN="isp.ngaredigital.com"
DB_NAME="isp_billing"
DB_USER="isp_billing_user"
# Generate a strong DB password
DB_PASS=$(openssl rand -base64 24 | tr -d '/+=' | head -c 24)

# Generate secrets
JWT_SECRET=$(openssl rand -hex 64)
ENCRYPTION_KEY=$(openssl rand -hex 16)

# --- STEP 1: Check prerequisites ---
log "Step 1/15: Checking prerequisites..."
command -v node >/dev/null 2>&1 || err "Node.js is not installed. Install Node.js 18 LTS or later."
command -v npm >/dev/null 2>&1 || err "npm is not installed."
command -v mysql >/dev/null 2>&1 || warn "mysql CLI not found. Database setup will need manual steps."
command -v nginx >/dev/null 2>&1 || err "Nginx is not installed. Run: apt install nginx"
command -v certbot >/dev/null 2>&1 || err "Certbot is not installed. Run: apt install certbot python3-certbot-nginx"
command -v redis-server >/dev/null 2>&1 || warn "Redis not found. Install: apt install redis-server"
command -v pm2 >/dev/null 2>&1 || warn "PM2 not found. Install: npm install -g pm2"

NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
info "Node.js version: $(node -v)"
info "npm version: $(npm -v)"

# --- STEP 2: Create directory structure ---
log "Step 2/15: Creating directory structure..."
mkdir -p "$APP_DIR"/{frontend/{admin,dashboard,customer,portal},backend,uploads,logs,backups,releases}
chown -R www-data:www-data "$APP_DIR" 2>/dev/null || true
chmod -R 755 "$APP_DIR"

# --- STEP 3: Set up MySQL database ---
log "Step 3/15: Setting up MySQL database..."
if command -v mysql >/dev/null 2>&1; then
  mysql -u root <<SQL 2>/dev/null || warn "Could not auto-create DB. Create manually."
CREATE DATABASE IF NOT EXISTS ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '${DB_USER}'@'127.0.0.1' IDENTIFIED BY '${DB_PASS}';
GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'127.0.0.1';
FLUSH PRIVILEGES;
SQL
  log "Database ${DB_NAME} and user ${DB_USER} created."
else
  warn "Run MySQL manually:"
  echo "  CREATE DATABASE ${DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
  echo "  CREATE USER '${DB_USER}'@'127.0.0.1' IDENTIFIED BY '${DB_PASS}';"
  echo "  GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'127.0.0.1';"
  echo "  FLUSH PRIVILEGES;"
fi

# --- STEP 4: Ensure Redis is running ---
log "Step 4/15: Checking Redis..."
if command -v redis-cli >/dev/null 2>&1; then
  if redis-cli ping >/dev/null 2>&1; then
    log "Redis is running."
  else
    systemctl start redis-server 2>/dev/null || service redis-server start 2>/dev/null || warn "Could not start Redis."
    systemctl enable redis-server 2>/dev/null || true
  fi
fi

# --- STEP 5: Install backend dependencies ---
log "Step 5/15: Installing backend dependencies..."
if [ -f "$APP_DIR/backend/package.json" ]; then
  cd "$APP_DIR/backend"
  npm ci --omit=dev 2>&1 || npm install --production 2>&1 || warn "npm install had warnings"
  log "Backend dependencies installed."
else
  warn "Backend package.json not found. Upload the backend files first."
fi

# --- STEP 6: Configure backend .env ---
log "Step 6/15: Configuring backend environment..."
cat > "$APP_DIR/backend/.env" << ENVEOF
NODE_ENV=production
DEMO_MODE=false
PORT=3000
APP_NAME=ISP Billing System
APP_URL=https://${DOMAIN}
FRONTEND_URL=https://${DOMAIN}
DB_TYPE=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USERNAME=${DB_USER}
DB_PASSWORD=${DB_PASS}
DB_NAME=${DB_NAME}
DB_SSL=false
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
JWT_SECRET=${JWT_SECRET}
JWT_EXPIRY=24h
JWT_REFRESH_EXPIRY=7d
ENCRYPTION_KEY=${ENCRYPTION_KEY}
CORS_ORIGINS=https://${DOMAIN}
MPESA_ENVIRONMENT=sandbox
MPESA_CONSUMER_KEY=
MPESA_CONSUMER_SECRET=
MPESA_PASSKEY=
MPESA_SHORTCODE=174379
MPESA_TRANSACTION_TYPE=CustomerPayBillOnline
MPESA_CALLBACK_URL=https://${DOMAIN}/api/v1/mpesa/callback
MPESA_STK_TIMEOUT=30
UPLOAD_DIR=${APP_DIR}/uploads
MAX_FILE_SIZE=10485760
LOG_LEVEL=info
LOG_FILE=${APP_DIR}/logs/app.log
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX=100
BULL_REDIS_HOST=127.0.0.1
BULL_REDIS_PORT=6379
BULL_QUEUE_PREFIX=isp
ACCOUNT_LOCKOUT_ENABLED=true
ACCOUNT_LOCKOUT_ATTEMPTS=5
ACCOUNT_LOCKOUT_MINUTES=15
SESSION_TIMEOUT_HOURS=24
FEATURE_VOUCHERS=true
FEATURE_SUBSCRIPTIONS=true
FEATURE_COMMISSIONS=true
FEATURE_REPORTS=true
ENVEOF

chmod 600 "$APP_DIR/backend/.env"
chown www-data:www-data "$APP_DIR/backend/.env" 2>/dev/null || true
log "Backend .env created with generated secrets."

# --- STEP 7: Run database migrations ---
log "Step 7/15: Running database migrations..."
cd "$APP_DIR/backend"
# TypeORM synchronize will create tables on first start
# Or run seed if npm script available
if [ -f "dist/database/seed.js" ]; then
  SEED=true node dist/database/seed.js 2>&1 || warn "Seed script had issues (tables may already exist)."
fi
log "Database setup complete."

# --- STEP 8: Configure Nginx ---
log "Step 8/15: Configuring Nginx..."
if [ -f "$APP_DIR/nginx-isp.conf" ]; then
  cp "$APP_DIR/nginx-isp.conf" /etc/nginx/sites-available/isp.ngaredigital.com
  ln -sf /etc/nginx/sites-available/isp.ngaredigital.com /etc/nginx/sites-enabled/
  rm -f /etc/nginx/sites-enabled/default
  nginx -t && systemctl reload nginx
  log "Nginx configured and reloaded."
else
  warn "Nginx config not found at $APP_DIR/nginx-isp.conf"
fi

# --- STEP 9: Install SSL certificate ---
log "Step 9/15: Installing SSL certificate..."
if nginx -t >/dev/null 2>&1; then
  certbot --nginx -d ${DOMAIN} --non-interactive --agree-tos --email admin@ngaredigital.com 2>&1 || {
    warn "Certbot auto-install failed. Run manually: certbot --nginx -d ${DOMAIN}"
  }
  # Auto-renewal
  (crontab -l 2>/dev/null; echo "0 3 * * * certbot renew --quiet --post-hook 'systemctl reload nginx'") | crontab -
  log "SSL certificate installed. Renewal cron added."
else
  warn "Nginx config not valid. Fix and run: certbot --nginx -d ${DOMAIN}"
fi

# --- STEP 10: Configure firewall ---
log "Step 10/15: Configuring firewall..."
if command -v ufw >/dev/null 2>&1; then
  ufw allow 22/tcp 2>/dev/null || true
  ufw allow 80/tcp 2>/dev/null || true
  ufw allow 443/tcp 2>/dev/null || true
  ufw deny 3000/tcp 2>/dev/null || true
  ufw deny 3306 2>/dev/null || true
  ufw deny 6379 2>/dev/null || true
  ufw --force enable 2>/dev/null || true
  log "Firewall configured."
fi

# --- STEP 11: Start backend with PM2 ---
log "Step 11/15: Starting backend with PM2..."
cd "$APP_DIR"
pm2 delete isp-billing-api 2>/dev/null || true
pm2 start ecosystem.config.json
pm2 save
pm2 startup systemd -u root --hp /root 2>/dev/null || pm2 startup
log "Backend started with PM2. Auto-start on reboot enabled."

# --- STEP 12: Set up log rotation ---
log "Step 12/15: Setting up log rotation..."
cat > /etc/logrotate.d/isp-billing << LOGROTATE
${APP_DIR}/logs/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 644 www-data www-data
    sharedscripts
    postrotate
        pm2 reloadLogs
    endscript
}
LOGROTATE
log "Log rotation configured."

# --- STEP 13: Test API ---
log "Step 13/15: Testing API..."
sleep 3
API_TEST=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:3000/api/v1/auth/login -X POST -H "Content-Type: application/json" -d '{"email":"test@test.com","password":"test"}' 2>/dev/null || echo "000")
if [ "$API_TEST" = "401" ] || [ "$API_TEST" = "200" ]; then
  log "Backend API is responding (HTTP ${API_TEST})."
else
  warn "API test returned HTTP ${API_TEST}. Check backend logs: pm2 logs isp-billing-api"
fi

# --- STEP 14: Health check ---
log "Step 14/15: Checking services..."
echo "  Nginx: $(systemctl is-active nginx 2>/dev/null || echo 'not running')"
echo "  MySQL: $(systemctl is-active mysql 2>/dev/null || systemctl is-active mysqld 2>/dev/null || echo 'not running')"
echo "  Redis: $(redis-cli ping 2>/dev/null || echo 'not responding')"
echo "  PM2:   $(pm2 list 2>/dev/null | grep isp-billing-api | grep online || echo 'not online')"

# --- STEP 15: Save credentials ---
log "Step 15/15: Saving deployment report..."
DEPLOY_REPORT="${APP_DIR}/backups/deployment-$(date +%Y%m%d-%H%M).txt"
cat > "$DEPLOY_REPORT" << REPORT
============================================================
ISP BILLING SYSTEM - DEPLOYMENT REPORT
Domain: https://${DOMAIN}
Deployed: $(date)
============================================================

DIRECTORIES:
  App root: ${APP_DIR}
  Frontend: ${APP_DIR}/frontend
  Backend:  ${APP_DIR}/backend
  Uploads:  ${APP_DIR}/uploads
  Logs:     ${APP_DIR}/logs

DATABASE:
  Host: 127.0.0.1:3306
  Name: ${DB_NAME}
  User: ${DB_USER}
  Pass: ${DB_PASS}

SECRETS:
  JWT Secret:     ${JWT_SECRET}
  Encryption Key: ${ENCRYPTION_KEY}

URLS:
  Admin Panel:  https://${DOMAIN}/admin
  Dashboard:    https://${DOMAIN}/dashboard
  Customer:     https://${DOMAIN}/customer
  Portal:       https://${DOMAIN}/portal
  API Base:     https://${DOMAIN}/api/v1
  API Health:   https://${DOMAIN}/api/v1/health
  API Docs:     https://${DOMAIN}/api/docs

TEST ACCOUNTS (created by seed):
  Super Admin:  admin@hotspot.com / Admin@123
  Business Owner: demo@hotspot.com / Demo@123

BACKUP:
  Files: ${APP_DIR}/backups/
  Database: ${APP_DIR}/backups/

MANAGEMENT COMMANDS:
  View logs:     pm2 logs isp-billing-api
  Restart API:   pm2 restart isp-billing-api
  Stop API:      pm2 stop isp-billing-api
  Status:        pm2 status
  Nginx reload:  systemctl reload nginx
  SSL renew:     certbot renew --dry-run

REPORT
chmod 600 "$DEPLOY_REPORT"
log "Deployment report saved to: $DEPLOY_REPORT"
log ""
log "========================================================"
log "  DEPLOYMENT COMPLETE"
log "  Open: https://${DOMAIN}/admin"
log "  Login: admin@hotspot.com / Admin@123"
log "========================================================"
