#!/usr/bin/env bash

set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ENV_FILE="$ROOT_DIR/.env"
ENV_EXAMPLE_FILE="$ROOT_DIR/.env.example"
PHP_CONTACT_FILE="$ROOT_DIR/public/contact.php"

require_command() {
  local command_name="$1"

  if ! command -v "$command_name" >/dev/null 2>&1; then
    echo "Missing required command: $command_name" >&2
    exit 1
  fi
}

escape_env_value() {
  local value="$1"

  value=${value//\\/\\\\}
  value=${value//"/\\"}
  value=${value//\$/\\$}

  printf '%s' "$value"
}

prompt_value() {
  local var_name="$1"
  local prompt_text="$2"
  local default_value="${3-}"
  local secret_mode="${4-false}"
  local input_value=''

  while true; do
    if [[ -n "$default_value" ]]; then
      if [[ "$secret_mode" == "true" ]]; then
        read -r -s -p "$prompt_text [$default_value]: " input_value
        echo
      else
        read -r -p "$prompt_text [$default_value]: " input_value
      fi
    else
      if [[ "$secret_mode" == "true" ]]; then
        read -r -s -p "$prompt_text: " input_value
        echo
      else
        read -r -p "$prompt_text: " input_value
      fi
    fi

    if [[ -z "$input_value" ]]; then
      input_value="$default_value"
    fi

    if [[ -n "$input_value" ]]; then
      printf -v "$var_name" '%s' "$input_value"
      return 0
    fi

    echo "A value is required."
  done
}

prompt_optional_value() {
  local var_name="$1"
  local prompt_text="$2"
  local default_value="${3-}"
  local secret_mode="${4-false}"
  local input_value=''

  if [[ -n "$default_value" ]]; then
    if [[ "$secret_mode" == "true" ]]; then
      read -r -s -p "$prompt_text [$default_value]: " input_value
      echo
    else
      read -r -p "$prompt_text [$default_value]: " input_value
    fi
  else
    if [[ "$secret_mode" == "true" ]]; then
      read -r -s -p "$prompt_text: " input_value
      echo
    else
      read -r -p "$prompt_text: " input_value
    fi
  fi

  if [[ -z "$input_value" ]]; then
    input_value="$default_value"
  fi

  printf -v "$var_name" '%s' "$input_value"
}

random_secret() {
  openssl rand -hex 32
}

load_existing_env() {
  if [[ -f "$ENV_FILE" ]]; then
    set -a
    # shellcheck disable=SC1090
    source "$ENV_FILE"
    set +a
  fi
}

select_smtp_mode() {
  local smtp_mode=''

  echo
  echo "Select SMTP mode:"
  echo "  1) SSL on port 465"
  echo "  2) STARTTLS on port 587"
  echo "  3) Local sendmail"

  while true; do
    read -r -p "Choose 1, 2, or 3 [1]: " smtp_mode
    smtp_mode="${smtp_mode:-1}"

    case "$smtp_mode" in
      1)
        SMTP_PORT="465"
        SMTP_SECURE="ssl"
        SMTP_REQUIRE_TLS="false"
        SMTP_USE_SENDMAIL="false"
        return 0
        ;;
      2)
        SMTP_PORT="587"
        SMTP_SECURE="auto"
        SMTP_REQUIRE_TLS="true"
        SMTP_USE_SENDMAIL="false"
        return 0
        ;;
      3)
        SMTP_PORT="587"
        SMTP_SECURE="auto"
        SMTP_REQUIRE_TLS="false"
        SMTP_USE_SENDMAIL="true"
        SMTP_HOST=""
        SMTP_USER=""
        SMTP_PASS=""
        SMTP_TLS_SERVERNAME=""
        return 0
        ;;
      *)
        echo "Invalid selection."
        ;;
    esac
  done
}

write_env_file() {
  local env_backup_file=''

  if [[ -f "$ENV_FILE" ]]; then
    env_backup_file="$ENV_FILE.backup.$(date +%Y%m%d%H%M%S)"
    cp "$ENV_FILE" "$env_backup_file"
    echo "Backed up existing .env to $env_backup_file"
  fi

  cat >"$ENV_FILE" <<EOF
PORT="$(escape_env_value "$PORT")"
APP_URL="$(escape_env_value "$APP_URL")"
APP_SECRET="$(escape_env_value "$APP_SECRET")"
ADMIN_API_TOKEN="$(escape_env_value "$ADMIN_API_TOKEN")"

STRIPE_SECRET_KEY="$(escape_env_value "$STRIPE_SECRET_KEY")"
STRIPE_WEBHOOK_SECRET="$(escape_env_value "$STRIPE_WEBHOOK_SECRET")"
STRIPE_PUBLISHABLE_KEY="$(escape_env_value "$STRIPE_PUBLISHABLE_KEY")"

STRIPE_PRICE_LANDING_PAGE_STARTER="$(escape_env_value "$STRIPE_PRICE_LANDING_PAGE_STARTER")"
STRIPE_PRICE_AI_CONCIERGE_ADDON="$(escape_env_value "$STRIPE_PRICE_AI_CONCIERGE_ADDON")"
STRIPE_PRICE_SEO_BOOST="$(escape_env_value "$STRIPE_PRICE_SEO_BOOST")"
STRIPE_PRICE_LIMITED_DROP="$(escape_env_value "$STRIPE_PRICE_LIMITED_DROP")"

DATABASE_URL="$(escape_env_value "$DATABASE_URL")"
DATABASE_SSL="$(escape_env_value "$DATABASE_SSL")"

SMTP_HOST="$(escape_env_value "$SMTP_HOST")"
SMTP_PORT="$(escape_env_value "$SMTP_PORT")"
SMTP_USER="$(escape_env_value "$SMTP_USER")"
SMTP_PASS="$(escape_env_value "$SMTP_PASS")"
SMTP_SECURE="$(escape_env_value "$SMTP_SECURE")"
SMTP_REQUIRE_TLS="$(escape_env_value "$SMTP_REQUIRE_TLS")"
SMTP_TLS_REJECT_UNAUTHORIZED="$(escape_env_value "$SMTP_TLS_REJECT_UNAUTHORIZED")"
SMTP_TLS_SERVERNAME="$(escape_env_value "$SMTP_TLS_SERVERNAME")"
SMTP_USE_SENDMAIL="$(escape_env_value "$SMTP_USE_SENDMAIL")"

FULFILLMENT_FROM_EMAIL="$(escape_env_value "$FULFILLMENT_FROM_EMAIL")"
FULFILLMENT_FROM_NAME="$(escape_env_value "$FULFILLMENT_FROM_NAME")"
FULFILLMENT_NOTIFY_EMAIL="$(escape_env_value "$FULFILLMENT_NOTIFY_EMAIL")"
FULFILLMENT_WEBHOOK_URL="$(escape_env_value "$FULFILLMENT_WEBHOOK_URL")"
EOF
}

print_next_steps() {
  echo
  echo "Setup complete."
  echo
  echo "Next steps in cPanel:"
  echo "1. Point your Node app root at: $ROOT_DIR"
  echo "2. Ensure your web root serves the public/ directory contents."
  echo "3. Restart the Node app in Setup Node.js App."
  echo "4. Test: $APP_URL/api/health"
  echo "5. Test: $APP_URL/contact.php"
  echo "6. Configure Stripe webhook endpoint: $APP_URL/api/stripe/webhook"
}

main() {
  cd "$ROOT_DIR"

  require_command npm
  require_command node
  require_command openssl

  load_existing_env

  echo "Preparing cPanel deployment in $ROOT_DIR"

  if [[ -f "$ENV_EXAMPLE_FILE" && ! -f "$ENV_FILE" ]]; then
    cp "$ENV_EXAMPLE_FILE" "$ENV_FILE"
  fi

  PORT="${PORT:-3000}"
  APP_URL_DEFAULT="${APP_URL:-https://your-domain.com}"
  APP_SECRET_DEFAULT="${APP_SECRET:-$(random_secret)}"
  ADMIN_API_TOKEN_DEFAULT="${ADMIN_API_TOKEN:-$(random_secret)}"
  STRIPE_PUBLISHABLE_KEY_DEFAULT="${STRIPE_PUBLISHABLE_KEY:-pk_live_replace_me}"
  DATABASE_SSL_DEFAULT="${DATABASE_SSL:-false}"
  SMTP_TLS_REJECT_UNAUTHORIZED_DEFAULT="${SMTP_TLS_REJECT_UNAUTHORIZED:-true}"
  FULFILLMENT_FROM_NAME_DEFAULT="${FULFILLMENT_FROM_NAME:-brokeCoder}"
  FULFILLMENT_WEBHOOK_URL_DEFAULT="${FULFILLMENT_WEBHOOK_URL:-}"

  prompt_value APP_URL "Public HTTPS URL" "$APP_URL_DEFAULT"
  prompt_value APP_SECRET "APP_SECRET" "$APP_SECRET_DEFAULT"
  prompt_value ADMIN_API_TOKEN "ADMIN_API_TOKEN" "$ADMIN_API_TOKEN_DEFAULT"

  prompt_value STRIPE_SECRET_KEY "Stripe secret key (sk_...)" "${STRIPE_SECRET_KEY:-sk_live_replace_me}" true
  prompt_value STRIPE_WEBHOOK_SECRET "Stripe webhook secret (whsec_...)" "${STRIPE_WEBHOOK_SECRET:-whsec_replace_me}" true
  prompt_value STRIPE_PUBLISHABLE_KEY "Stripe publishable key (pk_...)" "$STRIPE_PUBLISHABLE_KEY_DEFAULT"
  prompt_value STRIPE_PRICE_LANDING_PAGE_STARTER "Stripe price ID for Landing Page Starter" "${STRIPE_PRICE_LANDING_PAGE_STARTER:-price_replace_me}"
  prompt_value STRIPE_PRICE_AI_CONCIERGE_ADDON "Stripe price ID for AI Concierge Addon" "${STRIPE_PRICE_AI_CONCIERGE_ADDON:-price_replace_me}"
  prompt_value STRIPE_PRICE_SEO_BOOST "Stripe price ID for SEO Boost" "${STRIPE_PRICE_SEO_BOOST:-price_replace_me}"
  prompt_value STRIPE_PRICE_LIMITED_DROP "Stripe price ID for Limited Drop" "${STRIPE_PRICE_LIMITED_DROP:-price_replace_me}"

  prompt_value DATABASE_URL "PostgreSQL DATABASE_URL" "${DATABASE_URL:-postgres://user:password@localhost:5432/dbname}" true
  prompt_value DATABASE_SSL "DATABASE_SSL (true/false)" "$DATABASE_SSL_DEFAULT"

  select_smtp_mode

  if [[ "$SMTP_USE_SENDMAIL" != "true" ]]; then
    prompt_value SMTP_HOST "SMTP host" "${SMTP_HOST:-mail.your-domain.com}"
    prompt_value SMTP_USER "SMTP username" "${SMTP_USER:-support@your-domain.com}"
    prompt_value SMTP_PASS "SMTP password" "${SMTP_PASS:-}" true
    prompt_optional_value SMTP_TLS_SERVERNAME "SMTP TLS server name" "${SMTP_TLS_SERVERNAME:-$SMTP_HOST}"
  fi

  prompt_value SMTP_TLS_REJECT_UNAUTHORIZED "SMTP_TLS_REJECT_UNAUTHORIZED (true/false)" "$SMTP_TLS_REJECT_UNAUTHORIZED_DEFAULT"
  prompt_value FULFILLMENT_FROM_EMAIL "From email" "${FULFILLMENT_FROM_EMAIL:-support@your-domain.com}"
  prompt_value FULFILLMENT_FROM_NAME "From name" "$FULFILLMENT_FROM_NAME_DEFAULT"
  prompt_value FULFILLMENT_NOTIFY_EMAIL "Notification email" "${FULFILLMENT_NOTIFY_EMAIL:-support@your-domain.com}"
  prompt_optional_value FULFILLMENT_WEBHOOK_URL "Fulfillment webhook URL (optional)" "$FULFILLMENT_WEBHOOK_URL_DEFAULT"

  echo
  echo "Installing Node dependencies..."
  npm install --omit=dev

  if command -v composer >/dev/null 2>&1; then
    echo "Installing PHPMailer with Composer..."
    composer require phpmailer/phpmailer
  else
    echo "Composer not found. Skipping PHPMailer install."
    echo "Install it manually with: composer require phpmailer/phpmailer"
  fi

  write_env_file

  echo "Running Node syntax check..."
  npm run build

  if command -v php >/dev/null 2>&1 && [[ -f "$PHP_CONTACT_FILE" ]]; then
    echo "Linting public/contact.php..."
    php -l "$PHP_CONTACT_FILE"
  else
    echo "PHP CLI not found. Skipping contact.php lint."
  fi

  print_next_steps
}

main "$@"