#!/bin/bash

# Interactive release script
# Usage: ./release.sh

# Exit immediately if a command exits with a non-zero status
set -e

# Function to display error messages
error_exit() {
    echo "❌ ERROR: $1" >&2
    exit 1
}

# Function to display success messages
success_message() {
    echo "✅ SUCCESS: $1"
}

# Function to display info messages
info_message() {
    echo "ℹ️  INFO: $1"
}

# Function to display section headers
section_header() {
    echo ""
    echo "================================================"
    echo "$1"
    echo "================================================"
}

# Function to increment version based on user choice
increment_version() {
    local current_version="$1"
    local choice="$2"

    # Split version into parts
    IFS='.' read -ra VERSION_PARTS <<<"$current_version"
    local major=${VERSION_PARTS[0]}
    local minor=${VERSION_PARTS[1]}
    local patch=${VERSION_PARTS[2]}

    case $choice in
    1)
        # Increment major, reset minor and patch to 0
        major=$((major + 1))
        minor=0
        patch=0
        ;;
    2)
        # Increment minor, reset patch to 0
        minor=$((minor + 1))
        patch=0
        ;;
    3)
        # Increment patch only
        patch=$((patch + 1))
        ;;
    *)
        error_exit "Invalid choice: $choice"
        ;;
    esac

    echo "$major.$minor.$patch"
}

# Function to update package.json version
update_package_json() {
    local version="$1"
    local package_file="package.json"

    if [ ! -f "$package_file" ]; then
        error_exit "package.json not found in current directory"
    fi

    info_message "Updating version in $package_file to $version"

    # Update version using sed (macOS compatible)
    if [[ "$OSTYPE" == "darwin"* ]]; then
        sed -i '' "s/\"version\": \"[^\"]*\"/\"version\": \"$version\"/" "$package_file"
    else
        sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"$version\"/" "$package_file"
    fi

    # Verify the change
    local new_version=$(grep -m 1 '"version":' "$package_file" | awk -F '"' '{print $4}')
    if [ "$new_version" = "$version" ]; then
        success_message "package.json version updated to $version"
    else
        error_exit "Failed to update package.json version"
    fi
}

section_header "🚀 Interactive Release Process"

# Step 1: Check if we are on dev or master branch
info_message "Checking current branch..."
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" != "dev" ] && [ "$CURRENT_BRANCH" != "master" ] && [ "$CURRENT_BRANCH" != "main" ]; then
    error_exit "Must be on 'dev', 'master', or 'main' branch. Current branch: $CURRENT_BRANCH. Please switch to dev, master, or main branch first."
fi
success_message "Currently on $CURRENT_BRANCH branch"

# Step 2: Check for uncommitted changes
info_message "Checking for uncommitted changes..."
if [ -n "$(git status --porcelain)" ]; then
    echo "⚠️  WARNING: You have uncommitted changes:"
    git status --short
    read -p "Do you want to continue anyway? (y/n): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        error_exit "Please commit or stash your changes before release"
    fi
fi
success_message "Working directory is clean or user confirmed to continue"

# Step 3: Fetch latest changes from remote
info_message "Fetching latest changes from remote..."
git fetch origin || error_exit "Failed to fetch from remote"
success_message "Fetched latest changes from remote"

# Step 4: Check if local branch is behind remote
info_message "Checking if local $CURRENT_BRANCH branch is up to date..."
LOCAL_COMMIT=$(git rev-parse $CURRENT_BRANCH)
REMOTE_COMMIT=$(git rev-parse origin/$CURRENT_BRANCH)

if [ "$LOCAL_COMMIT" != "$REMOTE_COMMIT" ]; then
    info_message "Local $CURRENT_BRANCH branch is behind remote. Pulling latest changes..."
    git pull origin $CURRENT_BRANCH || error_exit "Failed to pull latest changes from origin/$CURRENT_BRANCH"
    success_message "Successfully pulled latest changes"
else
    success_message "Local $CURRENT_BRANCH branch is up to date"
fi

# Step 5: Get current version and display version selection menu
info_message "Getting current version..."

# Get current version from package.json
CURRENT_VERSION=$(grep -m 1 '"version":' package.json | awk -F '"' '{print $4}')
if [ -z "$CURRENT_VERSION" ]; then
    error_exit "Could not determine current version from package.json"
fi

# Split current version into parts for display
IFS='.' read -ra VERSION_PARTS <<<"$CURRENT_VERSION"
MAJOR=${VERSION_PARTS[0]}
MINOR=${VERSION_PARTS[1]}
PATCH=${VERSION_PARTS[2]}

section_header "Version Selection"
echo "📦 Current version: $CURRENT_VERSION"
echo ""
echo "Please select which version number to increment:"
echo ""
echo "1) Major version (${MAJOR}.${MINOR}.${PATCH} → $((MAJOR + 1)).0.0)"
echo "   Use for: Breaking changes, major new features"
echo ""
echo "2) Minor version (${MAJOR}.${MINOR}.${PATCH} → ${MAJOR}.$((MINOR + 1)).0)"
echo "   Use for: New features, backward-compatible changes"
echo ""
echo "3) Patch version (${MAJOR}.${MINOR}.${PATCH} → ${MAJOR}.${MINOR}.$((PATCH + 1)))"
echo "   Use for: Bug fixes, small improvements"
echo ""

# Get user choice
while true; do
    read -p "Enter your choice (1-3): " -n 1 -r
    echo
    case $REPLY in
    [1-3])
        CHOICE=$REPLY
        break
        ;;
    *)
        echo "❌ Invalid choice. Please enter 1, 2, or 3."
        ;;
    esac
done

# Calculate new version
NEW_VERSION=$(increment_version "$CURRENT_VERSION" "$CHOICE")
VERSION_TAG="v$NEW_VERSION"

section_header "Release Confirmation"
echo "📋 Release Summary:"
echo "   Current version: $CURRENT_VERSION"
echo "   New version:     $NEW_VERSION"
echo "   Tag to create:   $VERSION_TAG"
echo ""

# Final confirmation
read -p "Do you want to proceed with the release? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    info_message "Release cancelled by user"
    exit 0
fi

# Step 6: Verify the tag doesn't already exist
info_message "Checking if tag $VERSION_TAG already exists..."
if git rev-parse "$VERSION_TAG" >/dev/null 2>&1; then
    error_exit "Tag $VERSION_TAG already exists. This should not happen as we generated it automatically."
fi
success_message "Tag $VERSION_TAG is available"

section_header "Executing Release"

# Step 7: Update version in package.json
info_message "Updating version in package.json..."
update_package_json "$NEW_VERSION"
success_message "Version updated in package.json"

# Step 8: Stage and commit changes
info_message "Staging and committing version update..."
git add package.json || error_exit "Failed to stage package.json"
git commit -m "chore: bump version to $NEW_VERSION for release $VERSION_TAG" || error_exit "Failed to commit changes"
success_message "Version change committed"

# Step 10: Create the tag at the new commit
info_message "Creating tag $VERSION_TAG..."
git tag -a "$VERSION_TAG" -m "Release $VERSION_TAG" || error_exit "Failed to create tag"
success_message "Tag $VERSION_TAG created at current commit"

# Step 11: Push changes and tag to remote
info_message "Pushing changes and tag to remote..."
git push origin $CURRENT_BRANCH || error_exit "Failed to push changes to remote"
git push origin "$VERSION_TAG" || error_exit "Failed to push tag to remote"
success_message "Changes and tag pushed to remote"

section_header "🎉 Release Completed Successfully!"
echo "✅ Tag $VERSION_TAG has been created and pushed to remote"
echo "✅ Version updated from $CURRENT_VERSION to $NEW_VERSION"
echo "✅ Commit: $(git rev-parse HEAD)"
echo ""
echo "Jenkins will automatically deploy to Cloudflare Pages."
echo "🔗 Production: https://tg-live-game.pwtk-dev.work"
