#!/bin/bash
set -euo pipefail

export PATH="/usr/local/bin:/usr/local/cpanel/bin:/usr/local/cpanel/scripts:$PATH"

########################################
# INGRESO DE VARIABLES
########################################

if [[ $# -lt 4 ]]; then
  echo "Uso: ./setup_cd_project4.sh <base_name> <email> \"<title>\" <product> [password] [domain]"
  echo "Ejemplo: ./setup_cd_project4.sh juandev2 juan@mail.com \"Juan Dev Studio\" art-design"
  echo "Ejemplo: ./setup_cd_project4.sh juandev2 juan@mail.com \"Juan Dev Studio\" petite-website MyPass123 https://juandev2.bewpro.com"
  exit 1
fi

BASE_NAME="$1"
EMAIL="$2"
TITLE="$3"
PRODUCT="$4"
PASSWORD="${5:-$(openssl rand -base64 12 | tr -d '/+=')}"
DOMAIN_ARG="${6:-}"

# Opcional: exportar SKIP_ASSETS=true para saltar assets (por velocidad)
SKIP_ASSETS="${SKIP_ASSETS:-false}"
# Opcional: CLEAN_PROVISION=true para provisión limpia sin seed content (para resellers)
CLEAN_PROVISION="${CLEAN_PROVISION:-false}"

# Opcional: BRAND_COLORS para colores de marca
BRAND_COLORS="${BRAND_COLORS:-}"

########################################
# VARIABLES AUTOMÁTICAS
########################################

USERNAME="${BASE_NAME}"

# DOMAIN_NAME viene del argumento (subdominio legible) o fallback a BASE_NAME
if [[ -n "${DOMAIN_ARG}" ]]; then
  APP_URL="${DOMAIN_ARG}"
  DOMAIN_NAME=$(echo "${DOMAIN_ARG}" | sed 's|https://||' | sed 's|/.*||')
else
  DOMAIN_NAME="${BASE_NAME}.bewpro.com"
  APP_URL="https://${DOMAIN_NAME}"
fi

DB_NAME="${BASE_NAME}_bp"
DB_USER="${BASE_NAME}_bpuser"
DB_PASSWORD="${PASSWORD}"

APP_NAME="${BASE_NAME}"

REPO_SSH="git@github.com:LACOMPANIADIGITAL/cd-system.git"
REPO_REFERENCE="/opt/cd-system-reference.git"
PROJECT_DIR_NAME="${BASE_NAME}"

# IMPORTANTE: usar binary CLI explícito de ea-php82.
# `php` (que termina en /usr/local/bin/php) es un Perl wrapper de cPanel que
# invoca php-cgi (SAPI no-CLI). Composer aborta con "Composer cannot be run
# safely on non-CLI SAPIs with register_argc_argv=On" si se usa esa variante.
# El binary directo de ea-php82 sí es CLI puro.
PHP_BIN="/opt/cpanel/ea-php82/root/usr/bin/php"
[ -x "$PHP_BIN" ] || PHP_BIN="php"  # fallback al wrapper si ea-php82 no instalado
COMPOSER_BIN="composer"
COMPOSER_CACHE_DIR="/root/.composer-cache"

# DNS (Hostinger API) — solo para subdominios *.bewpro.com
HOSTINGER_DNS_ZONE="bewpro.com"
# Accept TARGET_SERVER_IP from orchestrator (process-airtable.sh passes it)
if [[ -n "${TARGET_SERVER_IP:-}" ]]; then
  HOSTINGER_SERVER_IP="${TARGET_SERVER_IP}"
else
  HOSTINGER_SERVER_IP=$(curl -s --max-time 5 https://api.ipify.org 2>/dev/null || hostname -I | awk '{print $1}')
fi
CONFIG_FILE="/root/scripts/.airtable.env"
[[ -f "$CONFIG_FILE" ]] && source "$CONFIG_FILE"
HOSTINGER_TOKEN="${HOSTINGER_TOKEN:-}"
WHM_API_TOKEN="${WHM_API_TOKEN:-}"

########################################
# FUNCIONES AUXILIARES
########################################

die() {
  echo "ERROR: $*" >&2
  exit 1
}

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || die "No se encontró el comando requerido: $1"
}

########################################
# FUNCIÓN: Crear registro DNS
# Extraída para poder llamarla en paso 6 (anticipado) y paso 9 (retry).
########################################

create_dns_record() {
  local subdomain="$1"
  # overwrite=true: si el subdomain ya tiene un A record (residuo de un test
  # anterior con mismo slug en otro VPS), lo reemplaza con el IP correcto.
  # Si dejáramos overwrite=false (default Hostinger), el record acumularía
  # múltiples IPs y el DNS round-robin mandaría al server equivocado → SORRY page.
  # overwrite=true SOLO afecta el record con name+type matching, no toda la zona.
  if [[ "${APP_URL}" == *".bewpro.com"* ]] && [[ -n "${HOSTINGER_TOKEN}" ]]; then
    DNS_RESULT=$(curl -s -X PUT \
      -H "Authorization: Bearer ${HOSTINGER_TOKEN}" \
      -H "Content-Type: application/json" \
      -d "{\"overwrite\": true, \"zone\": [{\"name\": \"${subdomain}\", \"type\": \"A\", \"ttl\": 3600, \"records\": [{\"content\": \"${HOSTINGER_SERVER_IP}\"}]}]}" \
      "https://developers.hostinger.com/api/dns/v1/zones/${HOSTINGER_DNS_ZONE}")

    if echo "${DNS_RESULT}" | grep -Eq "accepted|success"; then
      echo "[DNS] Registro creado: ${subdomain}.${HOSTINGER_DNS_ZONE} → ${HOSTINGER_SERVER_IP}" >&2
    else
      echo "[DNS] WARN: no pudo crearse automáticamente. Crear manualmente:" >&2
      echo "      ${subdomain}.bewpro.com → ${HOSTINGER_SERVER_IP}" >&2
      echo "      Respuesta API: ${DNS_RESULT}" >&2
    fi
  elif [[ "${APP_URL}" != *".bewpro.com"* ]]; then
    echo "[DNS] Dominio custom detectado — DNS manual: ${APP_URL} → ${HOSTINGER_SERVER_IP}" >&2
  else
    echo "[DNS] WARN: HOSTINGER_TOKEN no configurado." >&2
    echo "      Crear manualmente: ${subdomain}.bewpro.com → ${HOSTINGER_SERVER_IP}" >&2
  fi
}

########################################
# VALIDACIONES
########################################

if [[ "$(id -u)" -ne 0 ]]; then
  die "Este script debe ejecutarse como root."
fi

# cPanel limita username (común: máx 16; aquí usamos 14 por seguridad como ya manejas en otros flujos)
if [[ ! "$BASE_NAME" =~ ^[a-z0-9]{1,14}$ ]]; then
  die "base_name inválido. Solo minúsculas y números, máx 14 caracteres."
fi

if [[ ! "$EMAIL" =~ ^[^@[:space:]]+@[^@[:space:]]+\.[^@[:space:]]+$ ]]; then
  die "Email inválido: $EMAIL"
fi

require_cmd whmapi1
require_cmd uapi
require_cmd git
require_cmd "$PHP_BIN"
require_cmd "$COMPOSER_BIN"
require_cmd openssl
require_cmd curl

########################################
# INICIO
########################################

echo "=========================================" >&2
echo "  SETUP NUEVO PROYECTO: ${DOMAIN_NAME}"   >&2
echo "  Usuario cPanel: ${USERNAME}"            >&2
echo "  Email: ${EMAIL}"                        >&2
echo "  Título: ${TITLE}"                       >&2
echo "  Producto: ${PRODUCT}"                   >&2
echo "  URL: ${APP_URL}"                        >&2
echo "  SKIP_ASSETS: ${SKIP_ASSETS}"            >&2
echo "=========================================" >&2

########################################
# 1. Crear cuenta cPanel
########################################

echo "[1/10] Creando cuenta cPanel..." >&2

# Si CLEAN_PROVISION=true y la cuenta ya existe, dropearla primero para evitar
# password mismatch en MySQL (caso típico: retry de un proyecto que falló).
# Sin esto, el "CREATE USER IF NOT EXISTS" del step 2 deja el password viejo
# y el .env nuevo no puede conectar.
if [[ "${CLEAN_PROVISION}" == "true" ]] && id "${USERNAME}" &>/dev/null; then
  echo "[1/10] CLEAN=true — dropeando cuenta cPanel existente ${USERNAME}..." >&2
  whmapi1 removeacct user="${USERNAME}" keepdns=0 >/tmp/removeacct_${USERNAME}.log 2>&1 || true
  sleep 2
fi

CREATE_LOG="/tmp/createacct_${USERNAME}.log"
whmapi1 createacct \
  username="${USERNAME}" \
  domain="${DOMAIN_NAME}" \
  password="${DB_PASSWORD}" \
  contactemail="noreply@bewpro.com" >"${CREATE_LOG}" 2>&1 || true

# whmapi1 suele salir 0 aunque falle: inspeccionar log
if grep -q "result: 1" "${CREATE_LOG}"; then
  echo "[1/10] Cuenta creada." >&2
elif grep -qi "already exists" "${CREATE_LOG}"; then
  echo "[1/10] Cuenta ya existe — continuando (idempotente)." >&2
else
  echo "Error creando cuenta cPanel:" >&2
  grep -i "reason:" "${CREATE_LOG}" >&2 || cat "${CREATE_LOG}" >&2
  exit 1
fi

echo "[1/10] Esperando que el usuario esté disponible..." >&2
for _ in $(seq 1 15); do
  id "${USERNAME}" &>/dev/null && break
  sleep 2
done
id "${USERNAME}" &>/dev/null || die "usuario ${USERNAME} no disponible tras 30s"

########################################
# 2. Crear DB, usuario y permisos
########################################

echo "[2/10] Creando DB y usuario..." >&2

# Si CLEAN_PROVISION=true, dropear DB + MySQL user existentes para evitar
# residuos del intento previo (password mismatch entre user y .env).
if [[ "${CLEAN_PROVISION}" == "true" ]]; then
  mysql -e "DROP DATABASE IF EXISTS \`${DB_NAME}\`;" 2>/dev/null || true
  mysql -e "DROP USER IF EXISTS '${DB_USER}'@'localhost';" 2>/dev/null || true
fi

uapi --user="${USERNAME}" Mysql create_database name="${DB_NAME}" >/tmp/uapi_db_${USERNAME}.log 2>&1 || true
mysql -e "ALTER DATABASE \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || true

uapi --user="${USERNAME}" Mysql create_user name="${DB_USER}" password="${DB_PASSWORD}" >/tmp/uapi_user_${USERNAME}.log 2>&1 || true
uapi --user="${USERNAME}" Mysql set_privileges_on_database \
  user="${DB_USER}" \
  database="${DB_NAME}" \
  privileges=ALL >/tmp/uapi_grants_${USERNAME}.log 2>&1 || true

# Fix: crear usuario y grant directo via MySQL (uapi puede tardar o escapar mal underscores)
mysql -e "CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASSWORD}';" 2>/dev/null || true
mysql -e "GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'localhost'; FLUSH PRIVILEGES;" 2>/dev/null || true

echo "[2/10] DB ${DB_NAME} y USER ${DB_USER} listos." >&2

########################################
# 3. Copiar claves SSH al usuario
########################################

echo "[3/10] Configurando claves SSH..." >&2

mkdir -p "/home/${USERNAME}/.ssh"

[[ -f /root/.ssh/id_rsa ]] && cp /root/.ssh/id_rsa* "/home/${USERNAME}/.ssh/" || true
[[ -f /root/.ssh/id_ed25519 ]] && cp /root/.ssh/id_ed25519* "/home/${USERNAME}/.ssh/" || true

if compgen -G "/home/${USERNAME}/.ssh/*.pub" > /dev/null; then
  cat "/home/${USERNAME}/.ssh/"*.pub > "/home/${USERNAME}/.ssh/authorized_keys"
fi

chown -R "${USERNAME}:${USERNAME}" "/home/${USERNAME}/.ssh"
chmod 700 "/home/${USERNAME}/.ssh"
chmod 600 "/home/${USERNAME}/.ssh"/* || true
chmod 644 "/home/${USERNAME}/.ssh/"*.pub || true
chmod 600 "/home/${USERNAME}/.ssh/authorized_keys" || true

########################################
# 4. Crear estructura git-files
########################################

echo "[4/10] Preparando estructura git-files..." >&2

su - "${USERNAME}" -c "mkdir -p public_html/git-files/${PROJECT_DIR_NAME}" >&2

su - "${USERNAME}" -c "
  mkdir -p ~/.ssh
  ssh-keyscan github.com >> ~/.ssh/known_hosts 2>/dev/null || true
  chmod 700 ~/.ssh
  chmod 644 ~/.ssh/known_hosts
" >&2

########################################
# 5. Clonar cd-system (con reference local)
########################################

echo "[5/10] Clonando repositorio cd-system..." >&2

if [[ ! -d "${REPO_REFERENCE}" ]]; then
  echo "[5/10] Inicializando reference clone (primera vez, puede tardar)..." >&2
  git clone --bare "${REPO_SSH}" "${REPO_REFERENCE}" >&2
else
  git -C "${REPO_REFERENCE}" fetch --all --quiet >&2 || true
fi

if su - "${USERNAME}" -c "test -d public_html/git-files/${PROJECT_DIR_NAME}/.git" 2>/dev/null; then
  echo "[5/10] Repo ya existe — haciendo git pull (idempotente)." >&2
  su - "${USERNAME}" -c "
    cd public_html/git-files/${PROJECT_DIR_NAME} && \
    git fetch origin && \
    git checkout cd-system && \
    git pull --ff-only origin cd-system
  " >&2
else
  # Limpiar directorio si quedó de intento anterior fallido
  su - "${USERNAME}" -c "
    rm -rf public_html/git-files/${PROJECT_DIR_NAME}
    mkdir -p public_html/git-files/${PROJECT_DIR_NAME}
  " >&2
  su - "${USERNAME}" -c "
    cd public_html/git-files/${PROJECT_DIR_NAME} && \
    git clone --branch cd-system --reference ${REPO_REFERENCE} ${REPO_SSH} .
  " >&2
fi

########################################
# 6. Composer + env
########################################

echo "[6/10] Configurando Laravel..." >&2

su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  cp .env.example .env
" >&2

su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  sed -i \
    -e 's|^APP_NAME=.*|APP_NAME=\"${APP_NAME}\"|' \
    -e 's|^APP_ENV=.*|APP_ENV=production|' \
    -e 's|^APP_DEBUG=.*|APP_DEBUG=false|' \
    -e 's|^APP_URL=.*|APP_URL=${APP_URL}|' \
    -e 's|^DB_CONNECTION=.*|DB_CONNECTION=mysql|' \
    -e 's|^DB_HOST=.*|DB_HOST=localhost|' \
    -e 's|^DB_PORT=.*|DB_PORT=3306|' \
    -e 's|^DB_DATABASE=.*|DB_DATABASE=${DB_NAME}|' \
    -e 's|^DB_USERNAME=.*|DB_USERNAME=${DB_USER}|' \
    -e 's|^DB_PASSWORD=.*|DB_PASSWORD=${DB_PASSWORD}|' \
    -e 's|^RUN_PROJECT_SEEDER=.*|RUN_PROJECT_SEEDER=true|' \
    -e 's|^MAIL_MAILER=.*|MAIL_MAILER=sendmail|' \
    -e 's|^MAIL_HOST=.*|MAIL_HOST=localhost|' \
    -e 's|^MAIL_PORT=.*|MAIL_PORT=25|' \
    -e 's|^MAIL_USERNAME=.*|MAIL_USERNAME=null|' \
    -e 's|^MAIL_PASSWORD=.*|MAIL_PASSWORD=null|' \
    -e 's|^MAIL_ENCRYPTION=.*|MAIL_ENCRYPTION=null|' \
    -e 's|^MAIL_FROM_ADDRESS=.*|MAIL_FROM_ADDRESS=noreply@bewpro.com|' \
    -e 's|^MAIL_FROM_NAME=.*|MAIL_FROM_NAME=BewPro|' \
    .env
" >&2

APP_KEY_VALUE="base64:$(openssl rand -base64 32)"
su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  sed -i 's|^APP_KEY=.*|APP_KEY=${APP_KEY_VALUE}|' .env
" >&2

# ── FEATURE: Vendor cache compartido (opt-in) ───────────────────────────────
# BEWPRO_VENDOR_CACHE=true en .airtable.env activa este shortcut:
# - Calcula md5 del composer.lock del tenant
# - Si /opt/cd-vendor-cache/{hash}/vendor existe, copia (no symlink, para
#   evitar issues de permisos cross-user en cPanel) → ahorra ~30s
# - Si no existe, composer install normal + popula el cache para próximos tenants
# - Concurrency-safe: flock en /var/lock/cd-vendor-cache-{hash} previene que
#   dos provisions paralelas generen el mismo cache al mismo tiempo
USE_VENDOR_CACHE="${BEWPRO_VENDOR_CACHE:-false}"
VENDOR_CACHE_BASE="/opt/cd-vendor-cache"
VENDOR_INSTALLED=false

if [[ "${USE_VENDOR_CACHE}" == "true" ]]; then
  TENANT_DIR="/home/${USERNAME}/public_html/git-files/${PROJECT_DIR_NAME}"
  if [[ -f "${TENANT_DIR}/composer.lock" ]]; then
    LOCK_HASH=$(md5sum "${TENANT_DIR}/composer.lock" | cut -d' ' -f1 | head -c 16)
    CACHE_DIR="${VENDOR_CACHE_BASE}/${LOCK_HASH}"
    LOCK_FILE_VENDOR="/var/lock/cd-vendor-cache-${LOCK_HASH}"

    mkdir -p "${VENDOR_CACHE_BASE}"

    # Sección crítica protegida con flock (timeout 600s = 10min)
    (
      flock -x -w 600 200 || { echo "[VENDOR_CACHE] WARN: flock timeout, fallback a install fresh" >&2; exit 1; }

      if [[ -d "${CACHE_DIR}/vendor" ]] && [[ -f "${CACHE_DIR}/vendor/autoload.php" ]]; then
        echo "[6/10] Vendor cache HIT (hash=${LOCK_HASH}) — copiando..." >&2
        cp -a "${CACHE_DIR}/vendor" "${TENANT_DIR}/vendor"
        chown -R "${USERNAME}:${USERNAME}" "${TENANT_DIR}/vendor"
      else
        echo "[6/10] Vendor cache MISS — composer install + populate..." >&2
        su - "${USERNAME}" -c "
          cd public_html/git-files/${PROJECT_DIR_NAME} && \
          COMPOSER_CACHE_DIR=${COMPOSER_CACHE_DIR} ${COMPOSER_BIN} install --no-scripts --no-interaction --ignore-platform-reqs
        " >&2
        # Poblar cache para próximos tenants
        if [[ -f "${TENANT_DIR}/vendor/autoload.php" ]]; then
          mkdir -p "${CACHE_DIR}"
          cp -a "${TENANT_DIR}/vendor" "${CACHE_DIR}/vendor"
          chmod -R o+r "${CACHE_DIR}/vendor"
          echo "[6/10] Vendor cache POPULATED en ${CACHE_DIR}" >&2
        fi
      fi
    ) 200>"${LOCK_FILE_VENDOR}"

    # Verificar que vendor/ quedó bien antes de declarar éxito
    if [[ -f "${TENANT_DIR}/vendor/autoload.php" ]]; then
      VENDOR_INSTALLED=true
    fi
  fi
fi

# Fallback: install fresh si vendor cache off o falló
if ! $VENDOR_INSTALLED; then
  su - "${USERNAME}" -c "
    cd public_html/git-files/${PROJECT_DIR_NAME} && \
    COMPOSER_CACHE_DIR=${COMPOSER_CACHE_DIR} ${COMPOSER_BIN} install --no-scripts --no-interaction --ignore-platform-reqs
  " >&2
fi

su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  ${PHP_BIN} artisan package:discover --ansi
" >&2 || true

# Fix SSL peer verification para SMTP remoto (legacy VPS2 con cert genérico)
su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  grep -q '^MAIL_VERIFY_PEER=' .env || echo 'MAIL_VERIFY_PEER=false' >> .env && \
  grep -q '^MAIL_VERIFY_PEER_NAME=' .env || echo 'MAIL_VERIFY_PEER_NAME=false' >> .env && \
  grep -q '^MAIL_ALLOW_SELF_SIGNED=' .env || echo 'MAIL_ALLOW_SELF_SIGNED=true' >> .env
" >&2

# ── FEATURE: Mailers nombrados HOLA / NOREPLY ───────────────────────────────
# El tenant usa exim local (sendmail/localhost), pero los mailables de Laravel
# diferencian FROM segun naturaleza del mensaje:
#   - hola@bewpro.com    → relación humana (pedido recibido, reseller notify)
#   - noreply@bewpro.com → transaccional (credenciales, billing, suspensión)
# Las passwords se inyectan desde /root/scripts/.airtable.env si están definidas.
HOLA_USER="${HOLA_MAIL_USERNAME:-hola@bewpro.com}"
HOLA_PASS="${HOLA_MAIL_PASSWORD:-}"
NOREPLY_USER="${NOREPLY_MAIL_USERNAME:-noreply@bewpro.com}"
NOREPLY_PASS="${NOREPLY_MAIL_PASSWORD:-}"

su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  grep -q '^MAIL_USERNAME_HOLA=' .env || echo 'MAIL_USERNAME_HOLA=${HOLA_USER}' >> .env && \
  grep -q '^MAIL_PASSWORD_HOLA=' .env || echo 'MAIL_PASSWORD_HOLA=${HOLA_PASS}' >> .env && \
  grep -q '^MAIL_USERNAME_NOREPLY=' .env || echo 'MAIL_USERNAME_NOREPLY=${NOREPLY_USER}' >> .env && \
  grep -q '^MAIL_PASSWORD_NOREPLY=' .env || echo 'MAIL_PASSWORD_NOREPLY=${NOREPLY_PASS}' >> .env
" >&2

# ── FEATURE: Airtable creds para bewpro:check-billing ───────────────────────
# El tenant sincroniza Pipeline_Status desde Airtable cada hora (cron) hacia
# settings local, para que el middleware EnsureBillingActive muestre la
# página "sitio suspendido" cuando aplica.
# AIRTABLE_TABLE_ID en .airtable.env apunta a Projects (alias subscriptions_table).
# El tracking table es fijo (Subscriptions tabla en BewPro 2.0).
AIRTABLE_TOKEN_VAL="${AIRTABLE_TOKEN:-}"
AIRTABLE_BASE_ID_VAL="${AIRTABLE_BASE_ID:-}"
AIRTABLE_PROJECTS_TABLE_VAL="${AIRTABLE_TABLE_ID:-}"

su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  grep -q '^AIRTABLE_TOKEN=' .env || echo 'AIRTABLE_TOKEN=${AIRTABLE_TOKEN_VAL}' >> .env && \
  grep -q '^AIRTABLE_BASE_ID=' .env || echo 'AIRTABLE_BASE_ID=${AIRTABLE_BASE_ID_VAL}' >> .env && \
  grep -q '^AIRTABLE_SUBSCRIPTIONS_TABLE=' .env || echo 'AIRTABLE_SUBSCRIPTIONS_TABLE=${AIRTABLE_PROJECTS_TABLE_VAL}' >> .env && \
  grep -q '^AIRTABLE_SUBSCRIPTIONS_TRACKING_TABLE=' .env || echo 'AIRTABLE_SUBSCRIPTIONS_TRACKING_TABLE=tblnpr52JhFBBi2Mg' >> .env
" >&2

# ── FEATURE: BILLING_PUSH_SECRET ────────────────────────────────────────────
# Validación HMAC del endpoint /__internal__/billing-status que recibe pushes
# instantáneos del webhook Stripe (en bewpro22) hacia este tenant para
# suspender/reactivar el sitio sin esperar al cron horario.
BILLING_PUSH_SECRET_VAL="${BILLING_PUSH_SECRET:-}"
su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  grep -q '^BILLING_PUSH_SECRET=' .env || echo 'BILLING_PUSH_SECRET=${BILLING_PUSH_SECRET_VAL}' >> .env
" >&2

# ── FEATURE: reCAPTCHA v3 (antibots forms públicos) ────────────────────────
# Site MASTER 'BewPro Network' cubre bewpro.com + lacompaniadigital.com +
# subdomains. Si las vars vienen vacías, el middleware 'recaptcha' pasa todo
# (modo dev sin captcha). Las dos vars vienen de /root/scripts/.airtable.env.
RECAPTCHA_SITE_KEY_VAL="${RECAPTCHA_SITE_KEY:-}"
RECAPTCHA_SECRET_KEY_VAL="${RECAPTCHA_SECRET_KEY:-}"
su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  grep -q '^RECAPTCHA_SITE_KEY=' .env || echo 'RECAPTCHA_SITE_KEY=${RECAPTCHA_SITE_KEY_VAL}' >> .env && \
  grep -q '^RECAPTCHA_SECRET_KEY=' .env || echo 'RECAPTCHA_SECRET_KEY=${RECAPTCHA_SECRET_KEY_VAL}' >> .env
" >&2

# ── DNS ANTICIPADO ──────────────────────────────────────────────────────────
# Registramos el DNS aquí — mientras Composer instalaba ya ganamos tiempo.
# El paso 9 verifica si propagó y reintenta si falló.
DNS_SUBDOMAIN=$(echo "${APP_URL}" | sed 's|https://||' | sed 's|\.bewpro\.com.*||')
echo "[6/10] Registrando DNS anticipado para ganar tiempo de propagación..." >&2
create_dns_record "${DNS_SUBDOMAIN}"
# ────────────────────────────────────────────────────────────────────────────

########################################
# 7. Provisionar con bewpro:new
########################################

echo "[7/10] Provisionando proyecto con bewpro:new..." >&2

# Construir flags opcionales
EXTRA_FLAGS=""
if [[ "${SKIP_ASSETS}" == "true" ]]; then
  EXTRA_FLAGS="${EXTRA_FLAGS} --skip-assets"
  echo "[7/10] Aviso: SKIP_ASSETS=true, se omitirá procesamiento de assets." >&2
fi
if [[ "${CLEAN_PROVISION}" == "true" ]]; then
  EXTRA_FLAGS="${EXTRA_FLAGS} --clean"
  echo "[7/10] Modo: provisión limpia (--clean)" >&2
fi
if [[ -n "${BRAND_COLORS}" ]]; then
  EXTRA_FLAGS="${EXTRA_FLAGS} --colors='${BRAND_COLORS}'"
  echo "[7/10] Colores de marca: ${BRAND_COLORS}" >&2
fi

su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  ${PHP_BIN} artisan bewpro:new \
    '${EMAIL}' \
    '${TITLE}' \
    '${PRODUCT}' \
    --db='${DB_NAME}' \
    --url='${APP_URL}' \
    --password='${PASSWORD}' \
    ${EXTRA_FLAGS} \
    --no-email \
    --no-interaction
" >&2

su - "${USERNAME}" -c "
  cd public_html/git-files/${PROJECT_DIR_NAME} && \
  ${PHP_BIN} artisan storage:link
" >&2 || true

echo "[7/10] Proyecto provisionado." >&2

########################################
# 8. Crear .htaccess final
########################################

echo "[8/10] Generando .htaccess..." >&2

cat > "/home/${USERNAME}/public_html/.htaccess" <<EOF
<IfModule mod_rewrite.c>
  RewriteEngine On

  RewriteRule ^\.well-known/acme-challenge/ - [L,NC]
  RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/ [NC]

  RewriteCond %{REQUEST_URI} !^/git-files/${PROJECT_DIR_NAME}/public/ [NC]
  RewriteRule ^(.*)$ git-files/${PROJECT_DIR_NAME}/public/\$1 [L]
</IfModule>
EOF

chown "${USERNAME}:${USERNAME}" "/home/${USERNAME}/public_html/.htaccess"

########################################
# 9. Verificar / reintentar registro DNS
########################################

echo "[9/10] Verificando DNS (registrado anticipadamente en paso 6)..." >&2

DNS_SUBDOMAIN=$(echo "${APP_URL}" | sed 's|https://||' | sed 's|\.bewpro\.com.*||')

if [[ "${APP_URL}" == *".bewpro.com"* ]]; then
  ALREADY_RESOLVED=$(dig +short A "${DNS_SUBDOMAIN}.bewpro.com" @8.8.8.8 2>/dev/null \
    | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1 || true)

  if [[ "${ALREADY_RESOLVED}" == "${HOSTINGER_SERVER_IP}" ]]; then
    echo "[9/10] DNS ya propagado ✓ — saltando espera" >&2
  else
    echo "[9/10] DNS aún propagando (resuelve: ${ALREADY_RESOLVED:-sin respuesta}) — reintentando registro..." >&2
    create_dns_record "${DNS_SUBDOMAIN}"
  fi
elif [[ "${APP_URL}" != *".bewpro.com"* ]]; then
  echo "[9/10] Dominio custom detectado — DNS manual:" >&2
  echo "         ${APP_URL} → ${HOSTINGER_SERVER_IP}" >&2
fi

########################################
# 10. Instalar wildcard SSL ZeroSSL (con AutoSSL fallback)
########################################

echo "[10/10] Instalando wildcard SSL ZeroSSL en ${DOMAIN_NAME}..." >&2

WILDCARD_CRT="/root/.acme.sh/bewpro.com/bewpro.com.cer"
WILDCARD_KEY="/root/.acme.sh/bewpro.com/bewpro.com.key"
WILDCARD_CAB="/root/.acme.sh/bewpro.com/ca.cer"
WHM_TOKEN="${WHM_API_TOKEN:-}"
SSL_INSTALLED=false

if [[ -z "${WHM_TOKEN}" ]]; then
  echo "[10/10] WARN: WHM_API_TOKEN no configurado — saltando wildcard, intentando AutoSSL" >&2
elif [[ ! -f "${WILDCARD_CRT}" ]]; then
  echo "[10/10] WARN: Wildcard cert no encontrado en ${WILDCARD_CRT} — intentando AutoSSL" >&2
else
  SSL_INSTALL_DOMAIN="${DOMAIN_NAME}"
  SSL_RESULT=$(python3 -c "
import urllib.request, urllib.parse, ssl, json, sys
crt = open('${WILDCARD_CRT}').read().strip()
key = open('${WILDCARD_KEY}').read().strip()
cab = open('${WILDCARD_CAB}').read().strip()
token = '${WHM_TOKEN}'
domain = '${SSL_INSTALL_DOMAIN}'
data = urllib.parse.urlencode({'domain': domain, 'crt': crt, 'key': key, 'cabundle': cab}).encode()
req = urllib.request.Request(
    'https://localhost:2087/json-api/installssl?api.version=1',
    data=data,
    headers={'Authorization': 'whm root:' + token}
)
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
try:
    with urllib.request.urlopen(req, context=ctx) as resp:
        result = json.loads(resp.read())
        print(result['metadata']['result'])
except Exception as e:
    print('0', file=sys.stderr)
    print(0)
" 2>/dev/null)

  if [[ "${SSL_RESULT}" == "1" ]]; then
    echo "[10/10] Wildcard SSL instalado en ${DOMAIN_NAME} ✓" >&2
    SSL_INSTALLED=true
  else
    echo "[10/10] WARN: Wildcard SSL falló — intentando AutoSSL como fallback" >&2
  fi
fi

# Fallback: AutoSSL Let's Encrypt si wildcard no se aplicó.
# Solo dispara, no espera (es slow). El cert real saldrá después por cron.
if ! $SSL_INSTALLED; then
  echo "[10/10] Disparando AutoSSL en background (puede tardar 1-5 min)..." >&2
  uapi --user="${USERNAME}" SSL set_autossl_excluded_domains >/dev/null 2>&1 || true
  whmapi1 start_autossl_check_for_one_user username="${USERNAME}" >/dev/null 2>&1 || true
fi

########################################
# 11. Registrar cron schedule:run del tenant
########################################

echo "[11/12] Registrando cron schedule:run del tenant..." >&2

CRON_LINE="* * * * * cd /home/${USERNAME}/public_html/git-files/${PROJECT_DIR_NAME} && php artisan schedule:run >> /dev/null 2>&1"
EXISTING_CRON=$(crontab -l -u "${USERNAME}" 2>/dev/null || true)
if echo "${EXISTING_CRON}" | grep -qF "schedule:run"; then
  echo "[11/12] schedule:run ya estaba registrado, OK." >&2
else
  { echo "${EXISTING_CRON}"; echo "${CRON_LINE}"; } | crontab -u "${USERNAME}" -
  echo "[11/12] schedule:run registrado en cron de ${USERNAME}." >&2
fi

########################################
# 12. Validación post-provision (HTTP + SSL, soft-fail)
########################################
# Antes de declarar éxito, validamos que el sitio responde y que el cert SSL
# está bound al user correcto. Si HTTP no responde, NO abortamos (soft-fail):
# el setup técnico completó OK y el primer request puede tardar 1-2 min extra
# por PHP-FPM cold start. El orquestador igual debe enviar credenciales.

echo "[12/12] Validando provision (HTTP + SSL)..." >&2

# Warm-up — fuerza PHP-FPM a inicializar el vhost antes de los retries reales.
RESOLVED_IP=$(dig +short A "${DOMAIN_NAME}" @8.8.8.8 2>/dev/null \
  | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1 || true)
if [[ -n "${RESOLVED_IP}" ]]; then
  curl -sI -L -m 30 \
    --resolve "${DOMAIN_NAME}:443:${RESOLVED_IP}" \
    --resolve "${DOMAIN_NAME}:80:${RESOLVED_IP}" \
    "${APP_URL}/" -o /dev/null 2>/dev/null || true
  echo "[12/12] Warm-up request enviado (PHP-FPM debería estar listo)" >&2
fi

HTTP_OK=false
HTTP_CODE_LAST=""
for attempt in 1 2 3 4 5 6; do
  RESOLVED_IP=$(dig +short A "${DOMAIN_NAME}" @8.8.8.8 2>/dev/null \
    | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1 || true)
  if [[ -n "${RESOLVED_IP}" ]]; then
    HTTP_CODE=$(curl -sI -L -m 20 \
      --resolve "${DOMAIN_NAME}:443:${RESOLVED_IP}" \
      --resolve "${DOMAIN_NAME}:80:${RESOLVED_IP}" \
      "${APP_URL}/" -o /dev/null -w "%{http_code}" 2>/dev/null || echo "0")
    HTTP_CODE_LAST="${HTTP_CODE}"
    if [[ "${HTTP_CODE}" =~ ^[23] ]]; then
      HTTP_OK=true
      echo "[12/12] HTTP OK (${HTTP_CODE}, intento ${attempt})" >&2
      break
    fi
    echo "[12/12] HTTP intento ${attempt}/6: ${HTTP_CODE}" >&2
  else
    echo "[12/12] HTTP intento ${attempt}/6: DNS sin resolver" >&2
  fi
  sleep 8
done

if ! $HTTP_OK; then
  echo "[12/12] WARN: HTTP no responde 2xx/3xx tras 6 intentos (último: ${HTTP_CODE_LAST})" >&2
  echo "[12/12]       Sitio puede demorar 1-2 min adicionales en servir la primera request." >&2
fi

# SSL check: verificar que el cert servido es del dominio (no default vhost).
SSL_SUBJECT=$(echo | timeout 8 openssl s_client \
    -connect "${DOMAIN_NAME}:443" \
    -servername "${DOMAIN_NAME}" 2>/dev/null \
    | openssl x509 -noout -subject 2>/dev/null || true)

if echo "${SSL_SUBJECT}" | grep -qiE "${DOMAIN_NAME}|bewpro\.com"; then
  echo "[12/12] SSL bound OK al dominio ✓" >&2
else
  echo "[12/12] INFO: SSL se validará cuando propague el DNS / AutoSSL termine" >&2
fi

if $HTTP_OK; then
  echo "[12/12] ✅ Validación post-provision OK" >&2
else
  echo "[12/12] ⚠️  Validación con warnings (sitio responderá en breve, flujo sigue)" >&2
fi

########################################
# FIN
########################################

echo "=========================================" >&2
echo " PROYECTO CONFIGURADO EXITOSAMENTE"       >&2
echo " URL: ${APP_URL}"                         >&2
echo " Usuario cPanel: ${USERNAME}"             >&2
echo " DB: ${DB_NAME}"                          >&2
$HTTP_OK || echo " ⚠️  Validación HTTP soft-fail (sitio cargando)" >&2
echo "=========================================" >&2

# IMPORTANTE: Esta debe ser la ÚLTIMA línea (STDOUT limpio para orquestador)
echo "${APP_URL}"
exit 0
