#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export WP_CLI_STRICT_ARGS_MODE=1

# Load machine/user defaults
if [[ -f "$HOME/.wp-bootstraprc" ]]; then
  # shellcheck disable=SC1090
  source "$HOME/.wp-bootstraprc"
fi

# Sensible fallbacks if config missing
HERD_WORKSPACE="${HERD_WORKSPACE:-$HOME/Herd}"
MYSQL_HOST="${MYSQL_HOST:-127.0.0.1}"
MYSQL_PORT="${MYSQL_PORT:-3306}"
MYSQL_ROOT_USER="${MYSQL_ROOT_USER:-root}"
MYSQL_ROOT_PASS="${MYSQL_ROOT_PASS:-}"
DEFAULT_ADMIN_EMAIL="${DEFAULT_ADMIN_EMAIL:-dev@vincentdesign.ca}"
DEFAULT_ADMIN_USER="${DEFAULT_ADMIN_USER:-vdidev}"
THEME_STARTER_REPO="${THEME_STARTER_REPO:-https://github.com/WordPress/twentytwentyfour.git}"
DEFAULT_THEME_REMOTE_ORIGIN="${DEFAULT_THEME_REMOTE_ORIGIN:-}"
LOCAL_TLD="${LOCAL_TLD:-test}"

require() {
  command -v "$1" >/dev/null 2>&1 || { echo "Missing dependency: $1"; exit 1; }
}

PHP_BIN="${WP_PHP_BIN:-php}"

for bin in git curl openssl mysql composer npm; do
  require "$bin"
done
require "$PHP_BIN"

if command -v wp >/dev/null 2>&1; then
  WP_CLI_CMD=(wp)
else
  WP_CLI_PHAR_DEFAULT="$SCRIPT_DIR/wp-cli.phar"
  if [[ ! -f "$WP_CLI_PHAR_DEFAULT" && -f "$SCRIPT_DIR/windows/wp-cli.phar" ]]; then
    WP_CLI_PHAR_DEFAULT="$SCRIPT_DIR/windows/wp-cli.phar"
  fi
  WP_CLI_PHAR="${WP_CLI_PHAR:-$WP_CLI_PHAR_DEFAULT}"
  if [[ -f "$WP_CLI_PHAR" ]]; then
    WP_CLI_CMD=("$PHP_BIN" -f "$WP_CLI_PHAR" --)
  else
    echo "Missing dependency: wp (command) or wp-cli.phar (set WP_CLI_PHAR)." >&2
    exit 1
  fi
fi

invoke_wp() {
  local args=("$@")
  WP_CLI_STRICT_ARGS_MODE=1 "${WP_CLI_CMD[@]}" --path="$PROJECT_DIR" "${args[@]}"
}

usage() {
  cat <<'USAGE'
Usage: wp-bootstrap.sh --project-name "Example Site" [options]

Options:
  --project-name NAME            Human-friendly project name (required)
  --admin-user USER              WordPress admin username
  --admin-email EMAIL            WordPress admin email
  --theme-starter-repo URL       Git URL for the starter theme
  --herd-workspace PATH          Herd workspace directory
  --local-tld TLD                Local development TLD (e.g., test)
  --mysql-host HOST              MySQL host
  --mysql-port PORT              MySQL port
  --mysql-root-user USER         MySQL root username
  --mysql-root-pass PASS         MySQL root password
  --help                         Show this help and exit
USAGE
}

slugify() {
  # lower, spaces->-, strip non [a-z0-9-]
  echo "$1" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g;s/^-+|-+$//g'
}

randpass() {
  # 24 char base64, strip non-url-safe chars
  openssl rand -base64 24 | tr -d '\n' | tr -d '=/+' | cut -c1-24
}

prompt() {
  local q def ans
  q="$1"; def="${2:-}"
  if [[ -n "$def" ]]; then
    read -r -p "$q [$def]: " ans || true
    echo "${ans:-$def}"
  else
    read -r -p "$q: " ans || true
    echo "$ans"
  fi
}

setup_pages_and_reading() {
  echo "Setting up default pages and reading options..."

  HOME_ID=$(invoke_wp post list --post_type=page --name='home' --field=ID --format=ids)
  if [[ -z "$HOME_ID" ]]; then
    HOME_ID=$(invoke_wp post create --post_type=page --post_status=publish --post_title="Home" --porcelain)
  fi

  NEWS_ID=$(invoke_wp post list --post_type=page --name='news' --field=ID --format=ids)
  if [[ -z "$NEWS_ID" ]]; then
    NEWS_ID=$(invoke_wp post create --post_type=page --post_status=publish --post_title="News" --porcelain)
  fi

  for TITLE in "Page Not Found (Error 404)" "Contact Us"; do
    SLUG="$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9]+/-/g;s/^-+|-+$//g')"
    ID=$(invoke_wp post list --post_type=page --name="$SLUG" --field=ID --format=ids)
    [[ -z "$ID" ]] && invoke_wp post create --post_type=page --post_status=publish --post_title="$TITLE" --porcelain >/dev/null
  done

  invoke_wp option update show_on_front 'page'
  invoke_wp option update page_on_front "$HOME_ID"
  invoke_wp option update page_for_posts "$NEWS_ID"

  invoke_wp post delete 1 --force >/dev/null 2>&1 || true
  invoke_wp post delete 2 --force >/dev/null 2>&1 || true

  invoke_wp rewrite structure '/%postname%/'
  invoke_wp rewrite flush --hard
  echo "Default pages and reading options configured."
}

install_and_activate_plugins() {
  local LOG="wp-content/plugin-bootstrap.log"
  echo "=== $(date -u '+%F %T') :: Plugin bootstrap start ===" | tee -a "$LOG"

  local plugins_path=""
  if [[ -f "$PROJECT_DIR/plugins.json" ]]; then
    plugins_path="$PROJECT_DIR/plugins.json"
  elif [[ -f "$SCRIPT_DIR/plugins.json" ]]; then
    plugins_path="$SCRIPT_DIR/plugins.json"
  fi

  if [[ -n "$plugins_path" ]]; then
    local pretty_path="$plugins_path"
    [[ "$pretty_path" == "$PROJECT_DIR/"* ]] && pretty_path="plugins.json"
    echo "Installing plugins from $pretty_path..." | tee -a "$LOG"
    if command -v jq >/dev/null 2>&1; then
      jq -c '.[]' "$plugins_path" | while read -r item; do
        ZIP=$(echo "$item" | jq -r '.zip // empty')
        SLUG=$(echo "$item" | jq -r '.slug // empty')
        VER=$(echo "$item" | jq -r '.version // empty')
        ACT=$(echo "$item" | jq -r '.activate // false')

        if [[ -n "$ZIP" ]]; then
          echo "Installing from zip: $ZIP" | tee -a "$LOG"
          local args=(plugin install "$ZIP" --force)
          [[ "$ACT" == "true" ]] && args+=(--activate)
          if invoke_wp "${args[@]}"; then
            echo "OK zip: $ZIP (activate=$ACT)" | tee -a "$LOG"
          else
            echo "FAIL zip: $ZIP" | tee -a "$LOG"
          fi
        elif [[ -n "$SLUG" ]]; then
          local args=(plugin install "$SLUG" --force)
          [[ -n "$VER" ]] && args+=("--version=$VER")
          [[ "$ACT" == "true" ]] && args+=(--activate)
          echo "Installing slug: $SLUG ${VER:+(v$VER)}" | tee -a "$LOG"
          if invoke_wp "${args[@]}"; then
            echo "OK slug: $SLUG (activate=$ACT)" | tee -a "$LOG"
          else
            echo "FAIL slug: $SLUG" | tee -a "$LOG"
          fi
        else
          echo "SKIP item with no slug/zip: $item" | tee -a "$LOG"
        fi
      done
    else
      echo "$pretty_path found but jq is not installed; skipping plugin install." | tee -a "$LOG"
    fi
  else
    echo "No plugins.json present; skipping plugin install." | tee -a "$LOG"
  fi

  echo "=== $(date -u '+%F %T') :: Plugin bootstrap end ===" | tee -a "$LOG"
}

PROJECT_NAME_CLI=""
ADMIN_USER_CLI=""
ADMIN_EMAIL_CLI=""
THEME_STARTER_REPO_FLAG=0

while [[ $# -gt 0 ]]; do
  case "$1" in
    --project-name)
      [[ $# -lt 2 ]] && { echo "Missing value for --project-name" >&2; usage >&2; exit 1; }
      PROJECT_NAME_CLI="$2"
      shift 2
      ;;
    --admin-user)
      [[ $# -lt 2 ]] && { echo "Missing value for --admin-user" >&2; usage >&2; exit 1; }
      ADMIN_USER_CLI="$2"
      shift 2
      ;;
    --admin-email)
      [[ $# -lt 2 ]] && { echo "Missing value for --admin-email" >&2; usage >&2; exit 1; }
      ADMIN_EMAIL_CLI="$2"
      shift 2
      ;;
    --theme-starter-repo)
      [[ $# -lt 2 ]] && { echo "Missing value for --theme-starter-repo" >&2; usage >&2; exit 1; }
      THEME_STARTER_REPO="$2"
      THEME_STARTER_REPO_FLAG=1
      shift 2
      ;;
    --herd-workspace)
      [[ $# -lt 2 ]] && { echo "Missing value for --herd-workspace" >&2; usage >&2; exit 1; }
      HERD_WORKSPACE="$2"
      shift 2
      ;;
    --local-tld)
      [[ $# -lt 2 ]] && { echo "Missing value for --local-tld" >&2; usage >&2; exit 1; }
      LOCAL_TLD="$2"
      shift 2
      ;;
    --mysql-host)
      [[ $# -lt 2 ]] && { echo "Missing value for --mysql-host" >&2; usage >&2; exit 1; }
      MYSQL_HOST="$2"
      shift 2
      ;;
    --mysql-port)
      [[ $# -lt 2 ]] && { echo "Missing value for --mysql-port" >&2; usage >&2; exit 1; }
      MYSQL_PORT="$2"
      shift 2
      ;;
    --mysql-root-user)
      [[ $# -lt 2 ]] && { echo "Missing value for --mysql-root-user" >&2; usage >&2; exit 1; }
      MYSQL_ROOT_USER="$2"
      shift 2
      ;;
    --mysql-root-pass)
      [[ $# -lt 2 ]] && { echo "Missing value for --mysql-root-pass" >&2; usage >&2; exit 1; }
      MYSQL_ROOT_PASS="$2"
      shift 2
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      usage >&2
      exit 1
      ;;
  esac
done
echo "VDI WP Bootstrap (Herd + DBngin)"

PROJECT_NAME="${PROJECT_NAME_CLI:-}"
if [[ -z "$PROJECT_NAME" ]]; then
  PROJECT_NAME="$(prompt 'Project name (Human-readable)')"
fi
[[ -z "$PROJECT_NAME" ]] && { echo "Project name is required."; exit 1; }

PROJECT_SLUG="$(slugify "$PROJECT_NAME")"
FOLDER_NAME="$PROJECT_SLUG"
PROJECT_DIR="$HERD_WORKSPACE/$FOLDER_NAME"
LOCAL_URL="http://$PROJECT_SLUG.$LOCAL_TLD"

echo "Derived:"
echo "  slug:      $PROJECT_SLUG"
echo "  path:      $PROJECT_DIR"
echo "  local URL: $LOCAL_URL"
echo

if [[ -n "$ADMIN_USER_CLI" ]]; then
  ADMIN_USER="$ADMIN_USER_CLI"
else
  ADMIN_USER="$(prompt 'Admin username' "$DEFAULT_ADMIN_USER")"
fi

if [[ -n "$ADMIN_EMAIL_CLI" ]]; then
  ADMIN_EMAIL="$ADMIN_EMAIL_CLI"
else
  ADMIN_EMAIL="$(prompt 'Admin email' "$DEFAULT_ADMIN_EMAIL")"
fi

ADMIN_PASS="$(randpass)"

DB_NAME="vdi_${PROJECT_SLUG}"
DB_USER="$DB_NAME"
DB_PASS="$(randpass)"

if (( THEME_STARTER_REPO_FLAG )); then
  THEME_REPO_URL="$THEME_STARTER_REPO"
else
  THEME_REPO_URL="$(prompt 'Theme starter repo URL' "$THEME_STARTER_REPO")"
fi
THEME_DIR="wp-content/themes/${PROJECT_SLUG}-theme"
THEME_REMOTE_ORIGIN="$(prompt 'New theme repo remote (origin) URL (leave blank to skip push)' "$DEFAULT_THEME_REMOTE_ORIGIN")"

echo
echo "Creating project directory..."
mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR"

echo "Downloading WordPress core..."
invoke_wp core download --force

echo "Creating database and user in MySQL ($MYSQL_HOST:$MYSQL_PORT)..."
MYSQL_AUTH=(-h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_ROOT_USER")
if [[ -n "$MYSQL_ROOT_PASS" ]]; then
  MYSQL_AUTH+=(-p"$MYSQL_ROOT_PASS")
fi

if ! mysql "${MYSQL_AUTH[@]}" -e "SELECT VERSION();" >/dev/null 2>&1; then
  echo "Cannot connect to MySQL as root (${MYSQL_ROOT_USER}@${MYSQL_HOST}:${MYSQL_PORT})." >&2
  exit 1
fi

mysql "${MYSQL_AUTH[@]}" <<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';
CREATE USER IF NOT EXISTS '$DB_USER'@'127.0.0.1' IDENTIFIED BY '$DB_PASS';
CREATE USER IF NOT EXISTS '$DB_USER'@'%' IDENTIFIED BY '$DB_PASS';
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'localhost';
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'127.0.0.1';
GRANT ALL PRIVILEGES ON \`$DB_NAME\`.* TO '$DB_USER'@'%';
FLUSH PRIVILEGES;
SQL

if ! mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$DB_USER" -p"$DB_PASS" -D "$DB_NAME" -e "SELECT 1;" >/dev/null 2>&1; then
  echo "New MySQL user '$DB_USER' cannot access database '$DB_NAME' at ${MYSQL_HOST}:${MYSQL_PORT}." >&2
  exit 1
fi

echo "Generating wp-config.php..."
invoke_wp config create \
  --dbname="$DB_NAME" \
  --dbuser="$DB_USER" \
  --dbpass="$DB_PASS" \
  --dbhost="${MYSQL_HOST}:${MYSQL_PORT}" \
  --force

if invoke_wp config shuffle-salts >/dev/null 2>&1; then
  echo "Salt keys shuffled."
else
  echo "Fetching salts from api.wordpress.org..."
  SALTS="$(curl -fsSL https://api.wordpress.org/secret-key/1.1/salt/)"
  invoke_wp config set AUTH_KEY "dummy" --type=constant --raw >/dev/null 2>&1 || true
  "$PHP_BIN" -r 'file_put_contents("wp-config.php", preg_replace("/\\?>\\s*$/","",file_get_contents("wp-config.php"))."\n".'"'"$SALTS"'"'."\n");'
fi

echo "Installing WordPress..."
invoke_wp core install \
  --url="$LOCAL_URL" \
  --title="$PROJECT_NAME" \
  --admin_user="$ADMIN_USER" \
  --admin_password="$ADMIN_PASS" \
  --admin_email="$ADMIN_EMAIL"

invoke_wp option update siteurl "$LOCAL_URL"
invoke_wp option update home "$LOCAL_URL"

setup_pages_and_reading

HTACCESS_FILE="$PROJECT_DIR/.htaccess"
if [[ ! -f "$HTACCESS_FILE" ]]; then
  cat >"$HTACCESS_FILE" <<'HTACCESS'
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
HTACCESS
  echo "Created default .htaccess"
fi

echo "Cloning theme starter (history will be stripped)..."
TMP_DIR=".starter-tmp"
rm -rf "$TMP_DIR"
git clone --depth=1 "$THEME_REPO_URL" "$TMP_DIR"

mkdir -p "$(dirname "$THEME_DIR")"
rm -rf "$THEME_DIR"
mv "$TMP_DIR" "$THEME_DIR"
rm -rf "$THEME_DIR/.git"

if [[ -f "$THEME_DIR/style.css" ]]; then
  sed -i.bak "s/Theme Name:.*/Theme Name: ${PROJECT_NAME}/" "$THEME_DIR/style.css" || true
  sed -i.bak "s/Text Domain:.*/Text Domain: ${PROJECT_SLUG}-theme/" "$THEME_DIR/style.css" || true
  rm -f "$THEME_DIR/style.css.bak"
fi

echo "Installing theme dependencies and building assets..."
pushd "$THEME_DIR" >/dev/null
composer install
npm install
npm run build
popd >/dev/null

echo "Activating theme..."
invoke_wp theme activate "${PROJECT_SLUG}-theme" || {
  echo "Activation failed (maybe theme slug mismatch). Listing themes:"
  invoke_wp theme list
}

install_and_activate_plugins

echo "Initializing theme repo..."
pushd "$THEME_DIR" >/dev/null
git init -b main
git add -A
git commit -m "feat: bootstrap ${PROJECT_NAME} theme from starter"
if [[ -n "$THEME_REMOTE_ORIGIN" ]]; then
  git remote add origin "$THEME_REMOTE_ORIGIN"
  git push -u origin main
fi
popd >/dev/null

create_wpengine_staging() {
  if [[ -z "${WPE_API_TOKEN:-}" ]]; then
    echo "WPE_API_TOKEN not set; skipping staging creation."
    return
  fi
  echo "Stub: Add WPE API call here to create staging for ${PROJECT_SLUG}."
}
create_wpengine_staging

SUMMARY_FILE="$PROJECT_DIR/bootstrap-summary.txt"
cat > "$SUMMARY_FILE" <<TXT
VDI WP Bootstrap — Summary
===========================

Project:          $PROJECT_NAME
Slug:             $PROJECT_SLUG
Folder:           $PROJECT_DIR
Local URL:        $LOCAL_URL

DB Host:          $MYSQL_HOST
DB Port:          $MYSQL_PORT
DB Name:          $DB_NAME
DB User:          $DB_USER
DB Pass:          $DB_PASS

WP Admin User:    $ADMIN_USER
WP Admin Pass:    $ADMIN_PASS
WP Admin Email:   $ADMIN_EMAIL

Theme Dir:        $THEME_DIR
Theme Remote:     ${THEME_REMOTE_ORIGIN:-<none>}

Log files:
- Plugin install log: wp-content/plugin-bootstrap.log

Next steps:
- If Herd doesn’t auto-serve the folder, link it via Herd UI/CLI and open $LOCAL_URL
- Remove legacy activation.php from the starter theme if present (now handled by bootstrap)
- Wire CI/CD as needed (never push DB to production)
TXT

echo
echo "✅ Bootstrap complete."
echo "Summary saved to: $SUMMARY_FILE"
echo
cat "$SUMMARY_FILE"
