#!/usr/bin/env bash
# CNPERP Local Server installer — Linux and macOS
# Run from: CNPERP/deploy/local-server/install-cnperp-local.sh
set -euo pipefail

CLOUD_URL="${CLOUD_URL:-https://erp.cnpsolutions.co.bw}"
PORT="${PORT:-8010}"
DB_NAME="${DB_NAME:-cnperp_local}"
DB_USER="${DB_USER:-cnperp_user}"
DB_PASSWORD="${DB_PASSWORD:-}"
INSTALL_SERVICE=false
SKIP_DEPS=false
SKIP_DB=false

usage() {
  cat <<'EOF'
CNPERP Local Server installer (Linux / macOS)

Usage:
  ./install-cnperp-local.sh [options]

Options:
  --install-path PATH   CNPERP folder (default: auto — script parent or /opt/CNPERP or ~/CNPERP)
  --cloud-url URL       CNP cloud hub (default: https://erp.cnpsolutions.co.bw)
  --port PORT           HTTP port (default: 8010)
  --db-password PASS    PostgreSQL password for cnperp_user (generated if omitted)
  --install-service     Install systemd service (Linux, requires root)
  --skip-deps           Skip pip install
  --skip-db             Skip database bootstrap
  -h, --help            Show this help

After install:
  ./start-cnperp-server.sh
  Open http://localhost:8010/setup — license + company setup
  Cloud sync pushes LAN transactions to the online hub in near real time.
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --install-path) INSTALL_PATH="$2"; shift 2 ;;
    --cloud-url) CLOUD_URL="$2"; shift 2 ;;
    --port) PORT="$2"; shift 2 ;;
    --db-password) DB_PASSWORD="$2"; shift 2 ;;
    --install-service) INSTALL_SERVICE=true; shift ;;
    --skip-deps) SKIP_DEPS=true; shift ;;
    --skip-db) SKIP_DB=true; shift ;;
    -h|--help) usage; exit 0 ;;
    *) echo "Unknown option: $1"; usage; exit 1 ;;
  esac
done

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
resolve_install_root() {
  if [[ -n "${INSTALL_PATH:-}" ]]; then
    cd "$INSTALL_PATH"
    pwd
    return
  fi
  local candidate
  candidate="$(cd "$SCRIPT_DIR/../.." && pwd)"
  if [[ -f "$candidate/app/main.py" ]]; then
    echo "$candidate"
    return
  fi
  for candidate in /opt/CNPERP "$HOME/CNPERP"; do
    if [[ -f "$candidate/app/main.py" ]]; then
      echo "$candidate"
      return
    fi
  done
  echo "Cannot find CNPERP install root. Extract the ZIP so you have CNPERP/app/main.py" >&2
  echo "  Linux server: sudo unzip -d /opt cnperp-local-install-*.zip  → /opt/CNPERP" >&2
  echo "  Mac: unzip -d ~ cnperp-local-install-*.zip  → ~/CNPERP" >&2
  exit 1
}

step() { echo ""; echo "==> $*"; }
ok()   { echo "    [OK] $*"; }
warn() { echo "    [!!] $*"; }
fail() { echo "    [FAIL] $*"; exit 1; }

ROOT="$(resolve_install_root)"
cd "$ROOT"
step "Install path: $ROOT"

# Python
step "Checking Python"
if ! command -v python3 >/dev/null 2>&1; then
  fail "python3 not found. Ubuntu: sudo apt install python3 python3-venv python3-pip"
fi
PY_VER="$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
python3 -c 'import sys; sys.exit(0 if sys.version_info >= (3, 10) else 1)' || fail "Python 3.10+ required (found $PY_VER)"
ok "Python $PY_VER"

# PostgreSQL
step "Checking PostgreSQL"
if ! command -v psql >/dev/null 2>&1; then
  fail "psql not found. Ubuntu: sudo apt install postgresql postgresql-contrib"
fi
if ! command -v pg_isready >/dev/null 2>&1 || ! pg_isready -q 2>/dev/null; then
  warn "PostgreSQL may not be running. Ubuntu: sudo systemctl start postgresql"
fi
ok "PostgreSQL client available"

if [[ -z "$DB_PASSWORD" ]]; then
  DB_PASSWORD="$(python3 -c 'import secrets; print(secrets.token_urlsafe(12))')"
  ok "Generated database password (saved in .env)"
fi

step "Creating PostgreSQL database and user"
PSQL_SUPER=(sudo -u postgres psql)
if [[ "$(uname -s)" == "Darwin" ]]; then
  PSQL_SUPER=(psql -U postgres)
fi
if ! "${PSQL_SUPER[@]}" -tAc "SELECT 1" >/dev/null 2>&1; then
  warn "Could not connect as postgres superuser. Create manually:"
  echo "      CREATE USER $DB_USER WITH PASSWORD '...';"
  echo "      CREATE DATABASE $DB_NAME OWNER $DB_USER;"
else
  if ! "${PSQL_SUPER[@]}" -tAc "SELECT 1 FROM pg_roles WHERE rolname='$DB_USER'" | grep -q 1; then
    "${PSQL_SUPER[@]}" -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';"
  else
    "${PSQL_SUPER[@]}" -c "ALTER USER $DB_USER WITH PASSWORD '$DB_PASSWORD';"
  fi
  if ! "${PSQL_SUPER[@]}" -tAc "SELECT 1 FROM pg_database WHERE datname='$DB_NAME'" | grep -q 1; then
    "${PSQL_SUPER[@]}" -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;"
  fi
  "${PSQL_SUPER[@]}" -c "GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;"
  ok "Database $DB_NAME ready"
fi

# venv
step "Python virtual environment"
VENV="$ROOT/.venv"
if [[ ! -x "$VENV/bin/python" ]]; then
  python3 -m venv "$VENV"
  ok "Created .venv"
fi
if [[ "$SKIP_DEPS" != true ]]; then
  step "Installing Python dependencies"
  "$VENV/bin/pip" install --upgrade pip -q
  "$VENV/bin/pip" install -r "$ROOT/requirements.txt"
  ok "Dependencies installed"
fi

# .env
step "Writing configuration (.env)"
SECRET="$(python3 -c 'import secrets; print(secrets.token_urlsafe(32))')"
cat > "$ROOT/.env" <<EOF
DEPLOYMENT_MODE=local
ENVIRONMENT=production
DEBUG=False
DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@127.0.0.1:5432/${DB_NAME}
SECRET_KEY=${SECRET}
APP_HOST=0.0.0.0
APP_PORT=${PORT}
LICENSE_CLOUD_URL=${CLOUD_URL%/}
LICENSE_ENFORCEMENT=true
LICENSE_REQUIRED_FOR_SETUP=true
ALLOW_LEGACY_UNLICENSED=false
LICENSE_ALLOW_OFFLINE_SETUP=false
REDIS_URL=redis://127.0.0.1:6379
CLOUD_SYNC_ENABLED=true
CLOUD_SYNC_REALTIME=true
CLOUD_SYNC_INTERVAL_SECONDS=30
AUTO_PROVISION_CLOUD_MIRROR=true
EOF
ok ".env created (cloud sync enabled — LAN changes push to online hub)"

NODE_NAME="$(hostname -s 2>/dev/null || hostname)"
mkdir -p "$ROOT/deploy"
cat > "$ROOT/deploy/license-node.json" <<EOF
{
  "cloud_url": "${CLOUD_URL%/}",
  "license_key": "",
  "node_name": "${NODE_NAME}",
  "public_base_url": "",
  "machine_fingerprint": "",
  "node_id": "",
  "sync_token": ""
}
EOF
ok "deploy/license-node.json template"

if [[ "$SKIP_DB" != true ]]; then
  step "Initializing database"
  export LICENSE_CLOUD_URL="${CLOUD_URL%/}"
  "$VENV/bin/python" "$ROOT/scripts/bootstrap_local_install.py" --cloud-url "$CLOUD_URL" --port "$PORT"
fi

# Firewall (Linux ufw)
if command -v ufw >/dev/null 2>&1 && [[ "$EUID" -eq 0 ]]; then
  step "Firewall (ufw port $PORT)"
  ufw allow "$PORT/tcp" >/dev/null 2>&1 || true
  ok "ufw rule added (if ufw active)"
fi

# systemd
if [[ "$INSTALL_SERVICE" == true ]] && [[ "$(uname -s)" == "Linux" ]] && [[ "$EUID" -eq 0 ]]; then
  step "Installing systemd service cnperp-local"
  SVC_USER="${SVC_USER:-cnperp}"
  if ! id "$SVC_USER" &>/dev/null; then
    useradd -r -s /bin/false -d "$ROOT" "$SVC_USER" 2>/dev/null || true
  fi
  chown -R "$SVC_USER:$SVC_USER" "$ROOT"
  sed -e "s|__INSTALL_ROOT__|$ROOT|g" -e "s|__PORT__|$PORT|g" -e "s|__SVC_USER__|$SVC_USER|g" \
    "$SCRIPT_DIR/cnperp-local.service.template" > /etc/systemd/system/cnperp-local.service
  systemctl daemon-reload
  systemctl enable cnperp-local
  systemctl restart cnperp-local
  ok "Service cnperp-local enabled — sudo systemctl status cnperp-local"
fi

echo ""
echo "============================================="
echo "  Installation complete"
echo "============================================="
echo ""
echo "  1. Start server:  $SCRIPT_DIR/start-cnperp-server.sh"
echo "     Or (systemd):   sudo systemctl start cnperp-local"
echo "  2. Setup wizard:  http://localhost:${PORT}/setup"
echo "  3. LAN users:     http://<this-ip>:${PORT}"
echo "  4. After setup, cloud mirror syncs to: ${CLOUD_URL%/}"
echo "  5. Link node:     $SCRIPT_DIR/connect-cloud.sh (after license in deploy/license-node.json)"
echo ""
