#!/bin/bash

set -e

# Terminal colors and formatting
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m' # No Color

# Helper functions for pretty output
print_success() {
    echo -e "${GREEN}${BOLD}✓${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}${BOLD}⚠${NC} $1"
}

print_error() {
    echo -e "${RED}${BOLD}✗${NC} $1"
    exit 1
}

print_info() {
    echo -e "${BOLD}$1${NC}"
}

# Function to ask for confirmation
confirm() {
    local message="$1"
    echo -ne "${YELLOW}${BOLD}?${NC} $message ${BOLD}(y/N)${NC} "
    read -n 1 -r response
    echo
    case "$response" in
        [yY]) 
            return 0
            ;;
        *)
            echo -e "${RED}${BOLD}✗${NC} Operation cancelled"
            exit 1
            ;;
    esac
}

# Validate arguments
if [ $# -ne 1 ]; then
    echo -e "${RED}${BOLD}✗${NC} Usage: $0 <version>"
    
    # Show last tag as reference if we're in a git repo
    if git rev-parse --git-dir > /dev/null 2>&1; then
        LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
        if [ -n "$LAST_TAG" ]; then
            echo -e "  Last tag: ${BOLD}${LAST_TAG}${NC}"
        fi
    fi
    exit 1
fi

VERSION="$1"

# Validate version format (requires 'v' prefix)
if ! echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.-]+)?$'; then
    print_error "Invalid version format. Please use 'v' prefix with semantic versioning (e.g., v1.2.3, v1.2.3-prerelease.1)"
fi

# Check if we're on main branch
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" != "main" ]; then
    print_error "Not on main branch (currently on: $CURRENT_BRANCH)"
fi

# Create release branch
RELEASE_BRANCH="release/${VERSION}"
if git checkout -b "$RELEASE_BRANCH"; then
    print_success "Created and switched to branch ${BOLD}${RELEASE_BRANCH}${NC}"
else
    print_error "Failed to create release branch"
fi

# Check if working tree is clean (staged and unstaged changes)
if ! git diff-index --quiet HEAD -- || [ -n "$(git ls-files --others --exclude-standard)" ]; then
    print_error "Working tree is not clean. Please commit or stash changes first."
fi

# Check if local main is in sync with origin/main
git fetch origin main > /dev/null 2>&1
LOCAL=$(git rev-parse main)
REMOTE=$(git rev-parse origin/main)
if [ "$LOCAL" != "$REMOTE" ]; then
    print_error "Local main branch is out of sync with origin/main. Please pull or push changes first."
fi

# Strip 'v' prefix for Cargo.toml version
CARGO_VERSION="${VERSION#v}"

# Update the version using sed
if sed -i '' "s/^version = \".*\"/version = \"${CARGO_VERSION}\"/" Cargo.toml; then
    print_success "Updated version in Cargo.toml to ${BOLD}${CARGO_VERSION}${NC}"
else
    print_error "Failed to update version in Cargo.toml"
fi

# Verify the change
UPDATED_VERSION=$(grep "^version = " Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
if [ "$UPDATED_VERSION" != "$CARGO_VERSION" ]; then
    print_error "Version update verification failed. Expected: $CARGO_VERSION, Got: $UPDATED_VERSION"
fi

# Run cargo check to update Cargo.lock
if cargo check > /dev/null 2>&1; then
    print_success "Ran cargo check to update Cargo.lock"
else
    print_error "cargo check failed"
fi

# Add changed files
git add Cargo.toml Cargo.lock

# Commit changes if any
COMMIT_MSG="Release ${VERSION}"
if ! git diff --staged --quiet; then
    if git commit -m "$COMMIT_MSG"; then
        print_success "Committed changes"
    else
        print_error "Failed to commit changes"
    fi
    
    if ! confirm "Push release branch and create PR?"; then
        print_error "Release cancelled"
    fi
    
    if git push origin "$RELEASE_BRANCH"; then
        print_success "Pushed ${BOLD}${RELEASE_BRANCH}${NC} to origin"
    else
        print_error "Failed to push release branch to origin"
    fi
    
    # Create pull request
    if gh pr create -f; then
        print_success "Pull request created"
    else
        print_error "Failed to create pull request"
    fi
    if gh pr merge -s; then
        print_success "Pull request merged"
    else
        print_error "Failed to merge pull request"
    fi
    git switch main
    git fetch
    git pull
    git tag ${VERSION}
    git push origin ${VERSION}
    git branch -D ${RELEASE_BRANCH}
fi

print_success "Release ${BOLD}${VERSION}${NC} process initiated successfully!"
