#!/usr/bin/bash
set -u

APP_DIR="${APP_DIR:-/home/yousystemsnet/public_html}"
BRANCH="${BRANCH:-staging}"
LOG="${LOG:-${APP_DIR}/deploy.log}"
GIT="${GIT:-/usr/local/cpanel/3rdparty/lib/path-bin/git}"

REPO_OWNER="${REPO_OWNER:-yousystemsnet}"
WEBHOOK_URL="${WEBHOOK_URL:-}"

NEXTJS_DIR="${NEXTJS_DIR:-$APP_DIR}"
NEXTJS_BUILD_CMD="${NEXTJS_BUILD_CMD:-npm run build}"
NEXTJS_INSTALL_CMD="${NEXTJS_INSTALL_CMD:-}"
NEXTJS_RESTART_CMD="${NEXTJS_RESTART_CMD:-}"

log_msg() {
  echo "$(date -Iseconds) $*" >> "$LOG"
}

fail() {
  log_msg "ERROR: $*"
  send_webhook "failed" "Deploy failed (Next.js)" "$*"
  log_msg "==== DEPLOY FAILED (Next.js) ===="
  exit 1
}

send_webhook() {
  local status="$1"
  local message="$2"
  local details="$3"

  if [ -z "$WEBHOOK_URL" ]; then
    return 0
  fi

  local full_text="${message}"
  if [ -n "$details" ]; then
    full_text="${full_text}"$'\n'"${details}"
  fi

  full_text="${full_text//\\/\\\\}"
  full_text="${full_text//\"/\\\"}"
  full_text="${full_text//$'\n'/\\n}"
  local payload="{\"text\":\"${full_text}\"}"

  curl -s -X POST "$WEBHOOK_URL" \
    -H "Content-Type: application/json" \
    -d "$payload" \
    --max-time 10 \
    --connect-timeout 5 > /dev/null 2>&1
}

export REPO_HOME="${REPO_HOME:-/home/${REPO_OWNER}}"
export HOME="$REPO_HOME"
export PATH="/usr/bin:/bin:/usr/local/bin"
export GIT_SSH_COMMAND="ssh -F ${REPO_HOME}/.ssh/config -o BatchMode=yes -o StrictHostKeyChecking=accept-new"
export NODE_ENV="${NODE_ENV:-production}"
export NEXT_TELEMETRY_DISABLED="${NEXT_TELEMETRY_DISABLED:-1}"

log_msg "==== DEPLOY (Next.js) START (user=$(whoami)) ===="

if [ ! -d "$APP_DIR" ]; then
  fail "APP_DIR does not exist: $APP_DIR"
fi

cd "$APP_DIR" || fail "Cannot cd to $APP_DIR"

if [ ! -x "$GIT" ] && ! command -v git >/dev/null 2>&1; then
  fail "git not found (GIT=$GIT)"
fi
if [ ! -x "$GIT" ]; then
  GIT="$(command -v git)"
fi

$GIT config --global --add safe.directory "$APP_DIR" 2>/dev/null || true

if ! test -w "$APP_DIR/.git"; then
  RUN_AS=""
  if [ "$(id -u)" = "0" ] && [ -n "$REPO_OWNER" ]; then
    if command -v runuser &>/dev/null; then
      RUN_AS="runuser -u $REPO_OWNER --"
    elif command -v sudo &>/dev/null; then
      RUN_AS="sudo -u $REPO_OWNER"
    fi
  fi

  if [ -n "$RUN_AS" ]; then
    log_msg "Re-exec as $REPO_OWNER (current user=$(whoami))"
    exec $RUN_AS /usr/bin/bash "$0" "$@"
  fi

  fail "Cannot write to $APP_DIR/.git (running as $(whoami)). Run: sudo -u $REPO_OWNER $0"
fi

export GIT_USERNAME="${GIT_USERNAME:-}"
export GIT_PASSWORD="${GIT_PASSWORD:-}"
if [ -f "$APP_DIR/.deploy_env" ] && [ -r "$APP_DIR/.deploy_env" ]; then
  set -a
  # shellcheck source=/dev/null
  source "$APP_DIR/.deploy_env"
  set +a
  export GIT_USERNAME="${GIT_USERNAME:-}"
  export GIT_PASSWORD="${GIT_PASSWORD:-}"
  WEBHOOK_URL="${WEBHOOK_URL:-}"
  log_msg "Loaded $APP_DIR/.deploy_env"
else
  log_msg "No .deploy_env at $APP_DIR/.deploy_env (will try SSH git pull without password prompt)"
fi

git_pull_ssh() {
  log_msg "git pull origin $BRANCH (SSH/key)"
  if $GIT pull origin "$BRANCH" >> "$LOG" 2>&1; then
    return 0
  fi
  return 1
}

git_pull_expect() {
  if [ -z "$GIT_USERNAME" ] || [ -z "$GIT_PASSWORD" ]; then
    return 1
  fi
  if ! command -v expect &>/dev/null; then
    fail "'expect' is required for HTTPS git credentials. Install expect or use SSH keys in $REPO_HOME/.ssh"
  fi

  log_msg "git pull origin $BRANCH (expect HTTPS)"
  expect <<EOF >> "$LOG" 2>&1
set timeout 120
spawn $GIT pull origin $BRANCH
expect {
  -re "Username for .*:" {
    send "$GIT_USERNAME\r"
    exp_continue
  }
  -re "Password for .*:" {
    send "$GIT_PASSWORD\r"
    exp_continue
  }
  -re "passphrase for key" {
    send "$GIT_PASSWORD\r"
    exp_continue
  }
  "Permission denied" {
    puts "ERROR: Permission denied"
    exit 1
  }
  eof {
    catch wait result
    set code [lindex \$result 3]
    exit [expr {\$code == "" ? 0 : \$code}]
  }
  timeout {
    puts "ERROR: Timeout waiting for git pull"
    exit 1
  }
}
EOF
}

PULL_EXIT=1
if git_pull_ssh; then
  PULL_EXIT=0
elif git_pull_expect; then
  PULL_EXIT=0
fi

if [ "$PULL_EXIT" -ne 0 ]; then
  fail "git pull failed (see last lines in $LOG). Check .deploy_env GIT_USERNAME/GIT_PASSWORD or SSH key in $REPO_HOME/.ssh"
fi

if [ ! -d "$NEXTJS_DIR" ]; then
  fail "NEXTJS_DIR not found: $NEXTJS_DIR"
fi

if [ ! -f "$NEXTJS_DIR/package.json" ]; then
  fail "NEXTJS_DIR has no package.json: $NEXTJS_DIR"
fi

log_msg "==== NEXTJS BUILD START ($NEXTJS_DIR) ===="

if [ -z "$NEXTJS_INSTALL_CMD" ]; then
  if [ -f "$NEXTJS_DIR/pnpm-lock.yaml" ] && command -v pnpm >/dev/null 2>&1; then
    (cd "$NEXTJS_DIR" && pnpm install --frozen-lockfile) >> "$LOG" 2>&1 || fail "pnpm install failed"
  elif [ -f "$NEXTJS_DIR/yarn.lock" ] && command -v yarn >/dev/null 2>&1; then
    (cd "$NEXTJS_DIR" && yarn install --frozen-lockfile) >> "$LOG" 2>&1 || fail "yarn install failed"
  else
    (cd "$NEXTJS_DIR" && npm ci --prefer-offline) >> "$LOG" 2>&1 || \
      (cd "$NEXTJS_DIR" && npm install --prefer-offline) >> "$LOG" 2>&1 || fail "npm install failed"
  fi
else
  (cd "$NEXTJS_DIR" && bash -c "$NEXTJS_INSTALL_CMD") >> "$LOG" 2>&1 || fail "NEXTJS_INSTALL_CMD failed"
fi

(cd "$NEXTJS_DIR" && bash -c "$NEXTJS_BUILD_CMD") >> "$LOG" 2>&1 || fail "NEXTJS_BUILD_CMD failed"

if [ -n "$NEXTJS_RESTART_CMD" ]; then
  (cd "$NEXTJS_DIR" && bash -c "$NEXTJS_RESTART_CMD") >> "$LOG" 2>&1 || fail "NEXTJS_RESTART_CMD failed"
fi

log_msg "==== NEXTJS BUILD END ===="

COMMIT_AUTHOR=$($GIT log -1 --format='%an' 2>/dev/null || true)
COMMIT_MSG=$($GIT log -1 --format='%s' 2>/dev/null || true)
CONTENT="Deployed Successfully (Next.js)"$'\n'"Author: ${COMMIT_AUTHOR}"$'\n'"Commit Message: ${COMMIT_MSG}"
WRAPPED=$'```\n'"$CONTENT"$'\n''```'
send_webhook "success" "$WRAPPED" ""

log_msg "==== DEPLOY (Next.js) END ===="
