#!/usr/bin/env bash
#
# ROBI — установка Laravel Reverb на AlmaLinux + cPanel + Apache
#
# Запуск (на сервере по SSH):
#   chmod +x scripts/setup-reverb-cpanel.sh
#   sudo bash scripts/setup-reverb-cpanel.sh
#
# Перед запуском отредактируйте переменные в блоке CONFIG ниже.
#
set -euo pipefail

# =============================================================================
# CONFIG — обязательно проверьте перед запуском
# =============================================================================

CPANEL_USER="itcarrot"                          # пользователь cPanel
DOMAIN="robi.itcarrot.com"                      # домен приложения
APP_DIR="/home/${CPANEL_USER}/${DOMAIN}"        # путь к Laravel (document root)
PHP_BIN="/usr/local/bin/php"                     # php -v (ea-php83: /usr/bin/ea-php83)
REVERB_PORT="8080"                               # внутренний порт Reverb (не открывать наружу)
SERVICE_NAME="robi-reverb"                       # имя systemd-сервиса

# =============================================================================
# Вспомогательные функции
# =============================================================================

log()  { printf '\033[1;34m[robi-reverb]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[robi-reverb]\033[0m %s\n' "$*"; }
die()  { printf '\033[1;31m[robi-reverb] ОШИБКА:\033[0m %s\n' "$*" >&2; exit 1; }

need_root() {
    [[ "${EUID:-$(id -u)}" -eq 0 ]] || die "Запустите скрипт от root: sudo bash $0"
}

rand_key() {
    openssl rand -hex 16
}

rand_secret() {
    openssl rand -hex 32
}

detect_php() {
    if [[ -x "$PHP_BIN" ]]; then
        return
    fi
    for candidate in /usr/bin/ea-php83 /usr/bin/ea-php82 /usr/bin/php; do
        if [[ -x "$candidate" ]]; then
            PHP_BIN="$candidate"
            return
        fi
    done
    die "PHP не найден. Укажите PHP_BIN вручную в начале скрипта."
}

# =============================================================================
# 1. Проверки
# =============================================================================

need_root
detect_php

[[ -d "$APP_DIR" ]]           || die "Каталог приложения не найден: $APP_DIR"
[[ -f "$APP_DIR/artisan" ]]   || die "artisan не найден в $APP_DIR"
command -v openssl >/dev/null || die "Нужен openssl"
command -v systemctl >/dev/null || die "Нужен systemd"

log "PHP:     $PHP_BIN ($($PHP_BIN -r 'echo PHP_VERSION;'))"
log "App:     $APP_DIR"
log "Domain:  $DOMAIN"
log "User:    $CPANEL_USER"
log "Reverb:  127.0.0.1:${REVERB_PORT}"

# =============================================================================
# 2. Ключи Reverb и обновление .env
# =============================================================================

ENV_FILE="${APP_DIR}/.env"
ENV_BACKUP="${ENV_FILE}.bak.$(date +%Y%m%d_%H%M%S)"

if [[ ! -f "$ENV_FILE" ]]; then
    die "Файл .env не найден: $ENV_FILE"
fi

cp "$ENV_FILE" "$ENV_BACKUP"
log "Резервная копия .env: $ENV_BACKUP"

REVERB_APP_ID="robi"
REVERB_APP_KEY="$(rand_key)"
REVERB_APP_SECRET="$(rand_secret)"

set_env() {
    local key="$1"
    local value="$2"
    local file="$ENV_FILE"
    if grep -q "^${key}=" "$file" 2>/dev/null; then
        sed -i "s|^${key}=.*|${key}=${value}|" "$file"
    else
        printf '\n%s=%s\n' "$key" "$value" >> "$file"
    fi
}

set_env BROADCAST_CONNECTION   reverb
set_env REVERB_APP_ID          "$REVERB_APP_ID"
set_env REVERB_APP_KEY         "$REVERB_APP_KEY"
set_env REVERB_APP_SECRET      "$REVERB_APP_SECRET"
set_env REVERB_HOST            "$DOMAIN"
set_env REVERB_PORT            443
set_env REVERB_SCHEME          https
set_env REVERB_SERVER_HOST     127.0.0.1
set_env REVERB_SERVER_PORT     "$REVERB_PORT"
set_env REVERB_SERVER_PATH     /reverb
set_env VITE_REVERB_APP_KEY    "$REVERB_APP_KEY"
set_env VITE_REVERB_HOST       "$DOMAIN"
set_env VITE_REVERB_PORT       443
set_env VITE_REVERB_SCHEME     https
set_env VITE_REVERB_PATH       /reverb

chown "${CPANEL_USER}:${CPANEL_USER}" "$ENV_FILE"
log ".env обновлён (Reverb ключи сгенерированы заново)"

# =============================================================================
# 3. Systemd-сервис Reverb
# =============================================================================

UNIT_FILE="/etc/systemd/system/${SERVICE_NAME}.service"

cat > "$UNIT_FILE" <<EOF
[Unit]
Description=ROBI Laravel Reverb WebSocket (${DOMAIN})
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=${CPANEL_USER}
Group=${CPANEL_USER}
WorkingDirectory=${APP_DIR}
ExecStart=${PHP_BIN} artisan reverb:start --host=127.0.0.1 --port=${REVERB_PORT}
Restart=always
RestartSec=3
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}

# Ограничения (по желанию)
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable "${SERVICE_NAME}"
systemctl restart "${SERVICE_NAME}"

sleep 2
if systemctl is-active --quiet "${SERVICE_NAME}"; then
    log "Systemd: ${SERVICE_NAME} запущен"
else
    warn "Systemd: сервис не поднялся. Смотрите: journalctl -u ${SERVICE_NAME} -n 50 --no-pager"
fi

# =============================================================================
# 4. Apache proxy (cPanel userdata include)
# =============================================================================

# HTTP и HTTPS — оба варианта (cPanel rebuild подхватит оба)
APACHE_STD="/etc/apache2/conf.d/userdata/std/2_4/${CPANEL_USER}/${DOMAIN}"
APACHE_SSL="/etc/apache2/conf.d/userdata/ssl/2_4/${CPANEL_USER}/${DOMAIN}"
APACHE_CONF_NAME="reverb.conf"

APACHE_SNIPPET=$(cat <<'APACHE_EOF'
# ROBI Laravel Reverb — WebSocket proxy
# Сгенерировано scripts/setup-reverb-cpanel.sh

<IfModule mod_proxy.c>
    ProxyPreserveHost On
    ProxyRequests Off

    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^/reverb/app/(.*)$ ws://127.0.0.1:REVERB_PORT_PLACEHOLDER/reverb/app/$1 [P,L]
    RewriteCond %{HTTP:Upgrade} !=websocket [NC]
    RewriteRule ^/reverb/app/(.*)$ http://127.0.0.1:REVERB_PORT_PLACEHOLDER/reverb/app/$1 [P,L]

    ProxyPass        /reverb http://127.0.0.1:REVERB_PORT_PLACEHOLDER/reverb
    ProxyPassReverse /reverb http://127.0.0.1:REVERB_PORT_PLACEHOLDER/reverb
</IfModule>
APACHE_EOF
)

APACHE_SNIPPET="${APACHE_SNIPPET//REVERB_PORT_PLACEHOLDER/${REVERB_PORT}}"

mkdir -p "$APACHE_STD" "$APACHE_SSL"
echo "$APACHE_SNIPPET" > "${APACHE_STD}/${APACHE_CONF_NAME}"
echo "$APACHE_SNIPPET" > "${APACHE_SSL}/${APACHE_CONF_NAME}"
chmod 644 "${APACHE_STD}/${APACHE_CONF_NAME}" "${APACHE_SSL}/${APACHE_CONF_NAME}"

log "Apache include записан:"
log "  ${APACHE_STD}/${APACHE_CONF_NAME}"
log "  ${APACHE_SSL}/${APACHE_CONF_NAME}"

# Проверка модулей Apache
if httpd -M 2>/dev/null | grep -q proxy_wstunnel; then
    log "mod_proxy_wstunnel: включён"
else
    warn "mod_proxy_wstunnel не найден!"
    warn "В WHM → EasyApache 4 включите: mod_proxy, mod_proxy_http, mod_proxy_wstunnel"
    warn "Затем перезапустите Apache и снова выполните этот скрипт."
fi

if [[ -x /scripts/rebuildhttpdconf ]]; then
    log "Пересборка конфигурации Apache (cPanel)..."
    /scripts/rebuildhttpdconf
fi

if [[ -x /scripts/restartsrv_httpd ]]; then
    log "Перезапуск Apache..."
    /scripts/restartsrv_httpd
else
    systemctl restart httpd || systemctl restart apache2 || warn "Перезапустите Apache вручную"
fi

# =============================================================================
# 5. Laravel: кэш конфигурации
# =============================================================================

log "Очистка кэша Laravel..."
sudo -u "${CPANEL_USER}" -H bash -c "cd '${APP_DIR}' && ${PHP_BIN} artisan config:clear && ${PHP_BIN} artisan config:cache"

# =============================================================================
# 6. Проверки
# =============================================================================

log "Проверка порта Reverb..."
if ss -tlnp 2>/dev/null | grep -q ":${REVERB_PORT} "; then
    log "Порт ${REVERB_PORT} слушается"
else
    warn "Порт ${REVERB_PORT} не слушается — проверьте journalctl -u ${SERVICE_NAME}"
fi

log "Проверка HTTP-прокси /app ..."
HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' "https://${DOMAIN}/app/${REVERB_APP_ID}" || echo "000")
if [[ "$HTTP_CODE" != "000" && "$HTTP_CODE" != "404" ]]; then
    log "HTTPS /app/${REVERB_APP_ID} → HTTP ${HTTP_CODE} (ожидается не 404)"
else
    warn "HTTPS /app/${REVERB_APP_ID} → HTTP ${HTTP_CODE}"
    warn "Если 404 — проверьте Apache include и mod_proxy_wstunnel"
fi

# =============================================================================
# Готово
# =============================================================================

cat <<EOF

================================================================================
  Reverb установлен
================================================================================

  Домен:        https://${DOMAIN}
  WebSocket:    wss://${DOMAIN}/app/${REVERB_APP_KEY}
  Auth:         https://${DOMAIN}/api/broadcasting/auth
  Systemd:      systemctl status ${SERVICE_NAME}
  Логи:         journalctl -u ${SERVICE_NAME} -f

  ВАЖНО — пересоберите фронтенд (VITE_* читаются при сборке):
    cd ${APP_DIR}
    npm ci
    npm run build

  Проверка в браузере:
    DevTools → Network → WS → должно быть wss://${DOMAIN}/app/...
    Повторяющихся GET /api/notifications быть не должно.

  Откат .env:
    cp ${ENV_BACKUP} ${ENV_FILE}

================================================================================
EOF
