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

COMPOSE=./docker-compose.yaml
SERVICE=postgres
DATA_DIR=./database
ROLLBACK_TIMESTAMP=$(date +%Y%m%d_%H%M%S)

echo "🧪 Validating docker-compose config..."
docker compose -f "$COMPOSE" config > /dev/null || {
  echo "❌ docker-compose config failed. Restore aborted."
  exit 1
}

# Extract current Postgres image
CURRENT_IMG=$(docker compose -f "$COMPOSE" config | grep "image:" | grep "$SERVICE" | awk '{print $2}' || true)

if [[ -z "$CURRENT_IMG" ]]; then
  echo "❌ Could not detect current image for service '$SERVICE'."
  exit 1
fi

CURRENT_TAG=$(basename "$CURRENT_IMG")
CURRENT_VERSION=$(echo "$CURRENT_TAG" | cut -d'-' -f1) # e.g., 17.5

# Detect appropriate backup folder
BACKUP_CANDIDATES=($(ls -td ./database_backup_* 2>/dev/null || true))

if [[ ${#BACKUP_CANDIDATES[@]} -eq 0 ]]; then
  echo "❌ No backup directory found. Cannot determine previous version."
  echo "ℹ️ Available folders:"
  ls -1d ./database_backup_* || true
  exit 1
elif [[ ${#BACKUP_CANDIDATES[@]} -eq 1 ]]; then
  SELECTED_BACKUP="${BACKUP_CANDIDATES[0]}"
  echo "ℹ️ Only one backup found. Using: ${SELECTED_BACKUP}"
else
  SELECTED_BACKUP="${BACKUP_CANDIDATES[1]}"
  echo "ℹ️ Multiple backups found. Using second latest: ${SELECTED_BACKUP}"
fi

# Extract version from selected backup folder
OLD_TAG=$(basename "$SELECTED_BACKUP" | sed -E 's/database_backup_(([^_]+)-alpine).*/\1/')
OLD_IMG="postgres:${OLD_TAG}"

DELETED_UPGRADE_DIR=./database_upgraded_${CURRENT_VERSION}_${ROLLBACK_TIMESTAMP}

echo "⏪ Initiating rollback from Postgres ${CURRENT_TAG} to ${OLD_IMG}..."

# Step 1: Confirm backup exists
if [ ! -d "$SELECTED_BACKUP" ]; then
  echo "❌ Backup folder '${SELECTED_BACKUP}' not found. Aborting."
  exit 1
fi

# Step 2: Stop services
echo "🛑 Stopping running services..."
docker compose -f "$COMPOSE" down

# Step 3: Archive current (possibly broken) database
echo "📦 Archiving current database directory as '${DELETED_UPGRADE_DIR}'..."
mv "$DATA_DIR" "$DELETED_UPGRADE_DIR"

# Step 4: Restore previous version
echo "♻️ Restoring from backup folder '${SELECTED_BACKUP}'..."
cp -a "$SELECTED_BACKUP" "$DATA_DIR"

# Step 5: Restore image tag in docker-compose.yaml
echo "🔁 Reverting docker-compose image tag to Postgres ${OLD_IMG}..."
update_image_tag() {
  local svc="$1"
  local file="$2"
  local target_tag="$3"
  
  echo "🔁 Reverting docker-compose image tag for service '$svc' to Postgres: ${target_tag}..."

  # Use awk to scope updates within the service definition only
  awk -v service="$svc" -v new_tag="$target_tag" '
    BEGIN { in_service = 0 }
    /^[ ]{2}[a-zA-Z0-9_-]+:/ {
      in_service = ($1 == service ":") ? 1 : 0
    }
    in_service && /^\s*image:/ {
      sub(/postgres:[^"'"'"']+/, "postgres:" new_tag)
    }
    { print }
  ' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
}
update_image_tag "$SERVICE" "$COMPOSE" "$OLD_TAG"

# Step 6: Restart Postgres
echo "🚀 Starting Postgres service with restored image..."
docker compose -f "$COMPOSE" up -d "$SERVICE"

# Step 7: Final messages
echo "✅ Rollback complete!"
echo "🗃️ PostgreSQL downgraded to '${OLD_IMG}' and data restored from '${SELECTED_BACKUP}'."
echo "📦 The faulty upgrade has been archived in '${DELETED_UPGRADE_DIR}'."
echo "  - To clean: rm -rf ${DELETED_UPGRADE_DIR}"
echo "  - To verify: docker compose logs -f $SERVICE"

# Step 8: Restart full application
echo "🔄 Pulling latest images..."
if ! docker compose pull; then
  echo "❌ Failed to pull images. Aborting."
  exit 1
fi

echo "🔄 Starting full application stack..."
if ! docker compose up -d --force-recreate; then
  echo "❌ Failed to start application stack. Please check logs."
  exit 1
fi

echo "✅ Deployment completed successfully."