#!/usr/bin/env bash
# =============================================================================
#  Agency PM — VPS Auto-Installer
#  Tested on Ubuntu 22.04 / Debian 12
#  Run as root or a sudo user:  sudo bash install-vps.sh
# =============================================================================
set -e

# ── Colour helpers ────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
info()    { echo -e "${CYAN}[INFO]${NC}  $*"; }
success() { echo -e "${GREEN}[OK]${NC}    $*"; }
warn()    { echo -e "${YELLOW}[WARN]${NC}  $*"; }
error()   { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
section() { echo -e "\n${BOLD}${CYAN}══ $* ══${NC}"; }

# ── Banner ────────────────────────────────────────────────────────────────────
echo -e "${BOLD}${CYAN}"
echo "  ┌─────────────────────────────────────────┐"
echo "  │   Agency Project Manager — VPS Setup    │"
echo "  │   Laravel 11 + React 18 + MySQL          │"
echo "  └─────────────────────────────────────────┘"
echo -e "${NC}"

# ── Collect config ────────────────────────────────────────────────────────────
section "Configuration"
read -rp "  Domain (e.g. yourdomain.com)       : " DOMAIN
read -rp "  API subdomain prefix [api]          : " API_SUB; API_SUB=${API_SUB:-api}
read -rp "  App subdomain prefix [app]          : " APP_SUB; APP_SUB=${APP_SUB:-app}
read -rp "  MySQL root password                 : " -s DB_ROOT_PASS; echo
read -rp "  New database name [agencypm]        : " DB_NAME; DB_NAME=${DB_NAME:-agencypm}
read -rp "  New database user [agencypm_user]   : " DB_USER; DB_USER=${DB_USER:-agencypm_user}
read -rp "  New database password               : " -s DB_PASS; echo
read -rp "  Admin email for SSL (Let's Encrypt) : " ADMIN_EMAIL
read -rp "  App timezone [UTC]                  : " APP_TZ; APP_TZ=${APP_TZ:-UTC}

API_DOMAIN="${API_SUB}.${DOMAIN}"
APP_DOMAIN="${APP_SUB}.${DOMAIN}"
INSTALL_DIR="/var/www/agencypm"

echo ""
info "API  → https://${API_DOMAIN}"
info "App  → https://${APP_DOMAIN}"
info "Root → ${INSTALL_DIR}"
echo ""
read -rp "  Proceed? [y/N] " CONFIRM
[[ "$CONFIRM" =~ ^[Yy]$ ]] || { echo "Aborted."; exit 0; }

# ── System packages ───────────────────────────────────────────────────────────
section "System Packages"
apt-get update -qq
apt-get install -y -qq \
  curl wget git unzip zip nginx certbot python3-certbot-nginx \
  mysql-server mysql-client \
  software-properties-common apt-transport-https ca-certificates gnupg

# PHP 8.2
add-apt-repository -y ppa:ondrej/php > /dev/null 2>&1 || true
apt-get update -qq
apt-get install -y -qq \
  php8.2 php8.2-fpm php8.2-mysql php8.2-mbstring php8.2-xml php8.2-bcmath \
  php8.2-curl php8.2-zip php8.2-intl php8.2-tokenizer php8.2-pdo

# Node 20 via NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - > /dev/null 2>&1
apt-get install -y -qq nodejs
success "PHP $(php -r 'echo PHP_VERSION;') · Node $(node -v) · npm $(npm -v)"

# Composer
if ! command -v composer &>/dev/null; then
  info "Installing Composer..."
  curl -sS https://getcomposer.org/installer | php
  mv composer.phar /usr/local/bin/composer
fi
success "Composer $(composer --version --no-ansi | awk '{print $3}')"

# ── MySQL setup ───────────────────────────────────────────────────────────────
section "MySQL"
systemctl start mysql
mysql -uroot -p"${DB_ROOT_PASS}" <<SQL
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'localhost';
FLUSH PRIVILEGES;
SQL
success "Database '${DB_NAME}' and user '${DB_USER}' created"

# ── Clone / copy repo ─────────────────────────────────────────────────────────
section "Application Files"
mkdir -p "${INSTALL_DIR}"
if [ -d "/tmp/agencypm-src" ]; then
  info "Copying from /tmp/agencypm-src ..."
  cp -r /tmp/agencypm-src/backend  "${INSTALL_DIR}/backend"
  cp -r /tmp/agencypm-src/frontend "${INSTALL_DIR}/frontend"
elif command -v git &>/dev/null && [ -n "${GIT_REPO:-}" ]; then
  info "Cloning ${GIT_REPO} ..."
  git clone "${GIT_REPO}" "${INSTALL_DIR}/src"
  mv "${INSTALL_DIR}/src/backend"  "${INSTALL_DIR}/backend"
  mv "${INSTALL_DIR}/src/frontend" "${INSTALL_DIR}/frontend"
  rm -rf "${INSTALL_DIR}/src"
else
  warn "No source found at /tmp/agencypm-src and GIT_REPO not set."
  warn "Upload your project files to ${INSTALL_DIR}/backend and ${INSTALL_DIR}/frontend"
  warn "then re-run this script with --skip-files flag."
fi

# ── Backend (Laravel) ─────────────────────────────────────────────────────────
section "Laravel Backend"
cd "${INSTALL_DIR}/backend"

# .env
if [ ! -f .env ]; then
  cp .env.example .env
fi

# Patch .env values
sed_env() { sed -i "s|^${1}=.*|${1}=${2}|" .env; }
sed_env APP_URL          "https://${API_DOMAIN}"
sed_env APP_ENV          "production"
sed_env APP_DEBUG        "false"
sed_env APP_TIMEZONE     "${APP_TZ}"
sed_env DB_HOST          "127.0.0.1"
sed_env DB_DATABASE      "${DB_NAME}"
sed_env DB_USERNAME      "${DB_USER}"
sed_env DB_PASSWORD      "${DB_PASS}"
sed_env FRONTEND_URL     "https://${APP_DOMAIN}"
sed_env SANCTUM_STATEFUL_DOMAINS "${APP_DOMAIN}"
sed_env SESSION_DOMAIN   ".${DOMAIN}"

COMPOSER_ALLOW_SUPERUSER=1 composer install --no-dev --optimize-autoloader --quiet
php artisan key:generate --force
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan storage:link
php artisan migrate --force

# Create default admin via tinker
php artisan tinker --execute="
\App\Models\User::firstOrCreate(
  ['email' => 'admin@${DOMAIN}'],
  [
    'name'     => 'Admin',
    'password' => bcrypt('Admin@123'),
    'role'     => 'super_admin',
    'is_active'=> true,
  ]
);
echo 'Admin user ready.';
"

# Permissions
chown -R www-data:www-data "${INSTALL_DIR}/backend"
chmod -R 755 "${INSTALL_DIR}/backend/storage"
chmod -R 755 "${INSTALL_DIR}/backend/bootstrap/cache"
success "Laravel configured"

# ── Frontend (React) ──────────────────────────────────────────────────────────
section "React Frontend"
cd "${INSTALL_DIR}/frontend"

# patch Vite env
cat > .env.production <<ENV
VITE_API_URL=https://${API_DOMAIN}/api/v1
ENV

npm ci --silent
npm run build
success "React built → ${INSTALL_DIR}/frontend/dist"

# ── Nginx ─────────────────────────────────────────────────────────────────────
section "Nginx"

# API vhost
cat > /etc/nginx/sites-available/agencypm-api <<NGINX
server {
    listen 80;
    server_name ${API_DOMAIN};
    root ${INSTALL_DIR}/backend/public;
    index index.php;

    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";

    location / {
        try_files \$uri \$uri/ /index.php?\$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param HTTP_AUTHORIZATION \$http_authorization;
    }

    location ~ /\.ht { deny all; }
}
NGINX

# App vhost
cat > /etc/nginx/sites-available/agencypm-app <<NGINX
server {
    listen 80;
    server_name ${APP_DOMAIN};
    root ${INSTALL_DIR}/frontend/dist;
    index index.html;

    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
    add_header Cache-Control "no-cache, no-store, must-revalidate";

    location / {
        try_files \$uri \$uri/ /index.html;
    }

    location ~* \.(js|css|png|jpg|svg|ico|woff2?)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
NGINX

ln -sf /etc/nginx/sites-available/agencypm-api /etc/nginx/sites-enabled/
ln -sf /etc/nginx/sites-available/agencypm-app /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default

nginx -t && systemctl reload nginx
success "Nginx configured"

# ── SSL (Let's Encrypt) ───────────────────────────────────────────────────────
section "SSL Certificates"
certbot --nginx \
  -d "${API_DOMAIN}" \
  -d "${APP_DOMAIN}" \
  --non-interactive \
  --agree-tos \
  --email "${ADMIN_EMAIL}" \
  --redirect
success "SSL certificates installed"

# ── PHP-FPM tuning ────────────────────────────────────────────────────────────
section "PHP-FPM"
PHP_FPM_CONF="/etc/php/8.2/fpm/pool.d/www.conf"
sed -i 's/^pm = .*/pm = ondemand/'           "${PHP_FPM_CONF}"
sed -i 's/^pm.max_children = .*/pm.max_children = 20/' "${PHP_FPM_CONF}"
systemctl restart php8.2-fpm
success "PHP-FPM tuned"

# ── Queue worker (systemd) ────────────────────────────────────────────────────
section "Queue Worker"
cat > /etc/systemd/system/agencypm-queue.service <<SERVICE
[Unit]
Description=Agency PM Queue Worker
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=${INSTALL_DIR}/backend
ExecStart=/usr/bin/php artisan queue:work --sleep=3 --tries=3 --max-time=3600
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
SERVICE

systemctl daemon-reload
systemctl enable agencypm-queue
systemctl start agencypm-queue
success "Queue worker running"

# ── Scheduler cron ────────────────────────────────────────────────────────────
section "Cron Scheduler"
CRON_LINE="* * * * * www-data cd ${INSTALL_DIR}/backend && php artisan schedule:run >> /dev/null 2>&1"
echo "${CRON_LINE}" > /etc/cron.d/agencypm
success "Cron scheduler installed"

# ── Done ─────────────────────────────────────────────────────────────────────
section "Installation Complete"
echo ""
echo -e "${GREEN}${BOLD}  ✓ Agency PM is live!${NC}"
echo ""
echo -e "  🌐 App   → ${BOLD}https://${APP_DOMAIN}${NC}"
echo -e "  🔌 API   → ${BOLD}https://${API_DOMAIN}/api/v1${NC}"
echo ""
echo -e "  👤 Default admin login:"
echo -e "     Email    : ${BOLD}admin@${DOMAIN}${NC}"
echo -e "     Password : ${BOLD}Admin@123${NC}  ← change this immediately!"
echo ""
echo -e "${YELLOW}  Next steps:${NC}"
echo "  1. Log in and change the admin password"
echo "  2. Add your team members under Team > Add member"
echo "  3. Configure email (MAIL_* settings in ${INSTALL_DIR}/backend/.env)"
echo ""
