#!/bin/bash

# Version management script for T1 Tour Management System
# Usage: ./scripts/version.sh [major|minor|patch] [message] [--dev|--rc|--beta]

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Function to print colored output
print_status() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

print_header() {
    echo -e "${BLUE}================================${NC}"
    echo -e "${BLUE}  T1 Tour Management System${NC}"
    echo -e "${BLUE}  Version Management Tool${NC}"
    echo -e "${BLUE}================================${NC}"
}

# Check if required files exist
check_files() {
    local required_files=("VERSION" "CHANGELOG.md" "composer.json" "package.json")
    
    for file in "${required_files[@]}"; do
        if [ ! -f "$file" ]; then
            print_error "$file file not found!"
            exit 1
        fi
    done
}

# Get current version
get_current_version() {
    cat VERSION
}

# Update version in all files
update_version() {
    local new_version=$1
    
    print_status "Updating version to $new_version..."
    
    # Update VERSION file
    echo "$new_version" > VERSION
    
    # Update composer.json
    sed -i.bak "s/\"version\": \"[^\"]*\"/\"version\": \"$new_version\"/" composer.json
    rm composer.json.bak
    
    # Update package.json
    sed -i.bak "s/\"version\": \"[^\"]*\"/\"version\": \"$new_version\"/" package.json
    rm package.json.bak
    
    # Update README.md version badge
    sed -i.bak "s/badge\/version-[^-]*/badge\/version-$new_version/" README.md
    rm README.md.bak
    
    # Update README.md version text
    sed -i.bak "s/Current Version: \*\*[^*]*\*\*/Current Version: \*\*$new_version\*\*/" README.md
    rm README.md.bak
    
    print_status "Version updated successfully!"
}

# Update changelog
update_changelog() {
    local new_version=$1
    local release_type=${2:-"release"}
    local release_date=$(date +%Y-%m-%d)
    
    print_status "Updating CHANGELOG.md..."
    
    # Create temporary file
    temp_file=$(mktemp)
    
    # Add new version section at the top (after [Unreleased])
    awk -v version="$new_version" -v date="$release_date" -v type="$release_type" '
    /^## \[Unreleased\]/ {
        print
        print ""
        
        # Add appropriate header based on release type
        if (type == "dev") {
            print "## [" version "] - " date " (Development)"
            print ""
            print "### 🚀 Development Release"
            print "This version is deployed to development environment for team review and testing."
            print ""
        } else if (type == "rc") {
            print "## [" version "] - " date " (Release Candidate)"
            print ""
            print "### 🎯 Release Candidate"
            print "This version is a release candidate for final testing."
            print ""
        } else if (type == "beta") {
            print "## [" version "] - " date " (Beta)"
            print ""
            print "### 🔧 Beta Release"
            print "This version is in beta testing phase."
            print ""
        } else {
            print "## [" version "] - " date
            print ""
        }
        
        print "### Added"
        print ""
        print "### Changed"
        print ""
        print "### Deprecated"
        print ""
        print "### Removed"
        print ""
        print "### Fixed"
        print ""
        print "### Security"
        print ""
        next
    }
    { print }
    ' CHANGELOG.md > "$temp_file"
    
    # Replace original file
    mv "$temp_file" CHANGELOG.md
    
    print_status "CHANGELOG.md updated successfully!"
}

# Calculate new version
calculate_new_version() {
    local current_version=$1
    local version_type=$2
    local pre_release_type=${3:-""}
    
    # Remove any existing pre-release suffix
    local base_version=$(echo "$current_version" | sed 's/-.*$//')
    
    IFS='.' read -ra VERSION_PARTS <<< "$base_version"
    local major=${VERSION_PARTS[0]}
    local minor=${VERSION_PARTS[1]}
    local patch=${VERSION_PARTS[2]}
    
    local new_base_version=""
    case $version_type in
        "major")
            new_base_version="$((major + 1)).0.0"
            ;;
        "minor")
            new_base_version="$major.$((minor + 1)).0"
            ;;
        "patch")
            new_base_version="$major.$minor.$((patch + 1))"
            ;;
        *)
            print_error "Invalid version type. Use: major, minor, or patch"
            exit 1
            ;;
    esac
    
    # Add pre-release suffix if specified
    if [ -n "$pre_release_type" ]; then
        # Get the next pre-release number
        local existing_pre_releases=$(git tag --list "v$new_base_version-$pre_release_type.*" | sort -V)
        local next_number=1
        
        if [ -n "$existing_pre_releases" ]; then
            local last_pre_release=$(echo "$existing_pre_releases" | tail -n 1)
            if [[ $last_pre_release =~ $pre_release_type\.([0-9]+)$ ]]; then
                next_number=$((BASH_REMATCH[1] + 1))
            fi
        fi
        
        echo "$new_base_version-$pre_release_type.$next_number"
    else
        echo "$new_base_version"
    fi
}

# Parse command line arguments
parse_arguments() {
    local version_type=""
    local commit_message=""
    local release_type="release"
    local pre_release_type=""
    
    while [[ $# -gt 0 ]]; do
        case $1 in
            --dev)
                release_type="dev"
                pre_release_type="dev"
                shift
                ;;
            --rc)
                release_type="rc"
                pre_release_type="rc"
                shift
                ;;
            --beta)
                release_type="beta"
                pre_release_type="beta"
                shift
                ;;
            major|minor|patch)
                version_type="$1"
                shift
                ;;
            *)
                if [ -z "$commit_message" ]; then
                    commit_message="$1"
                fi
                shift
                ;;
        esac
    done
    
    echo "$version_type|$commit_message|$release_type|$pre_release_type"
}

# Main function
main() {
    print_header
    
    # Check if we're in the right directory
    if [ ! -f "artisan" ]; then
        print_error "This script must be run from the Laravel project root directory!"
        exit 1
    fi
    
    # Check required files
    check_files
    
    # Get current version
    current_version=$(get_current_version)
    print_status "Current version: $current_version"
    
    # Parse arguments
    IFS='|' read -r version_type commit_message release_type pre_release_type <<< "$(parse_arguments "$@")"
    
    # Check arguments
    if [ -z "$version_type" ]; then
        print_status "Current version: $current_version"
        print_status "Usage: $0 [major|minor|patch] [optional: commit message] [--dev|--rc|--beta]"
        print_status ""
        print_status "Release types:"
        print_status "  --dev: Create development version (e.g., 1.0.1-dev.1)"
        print_status "  --rc: Create release candidate (e.g., 1.0.1-rc.1)"
        print_status "  --beta: Create beta version (e.g., 1.0.1-beta.1)"
        print_status "  (no flag): Create production release"
        exit 0
    fi
    
    # Calculate new version
    new_version=$(calculate_new_version "$current_version" "$version_type" "$pre_release_type")
    print_status "New version will be: $new_version"
    
    # Set default commit message if not provided
    if [ -z "$commit_message" ]; then
        local release_type_text=""
        case $release_type in
            "dev") release_type_text="development" ;;
            "rc") release_type_text="release candidate" ;;
            "beta") release_type_text="beta" ;;
            *) release_type_text="release" ;;
        esac
        commit_message="$release_type_text version $new_version"
    fi
    
    # Show release type information
    case $release_type in
        "dev")
            print_status "This will create a DEVELOPMENT version for team review"
            print_warning "Development versions are for team review and testing"
            ;;
        "rc")
            print_status "This will create a RELEASE CANDIDATE version"
            print_warning "RC versions are for final testing before production"
            ;;
        "beta")
            print_status "This will create a BETA version"
            print_warning "Beta versions are for early testing and feedback"
            ;;
        *)
            print_status "This will create a PRODUCTION release"
            print_warning "Production releases are final and should be stable"
            ;;
    esac
    
    # Confirm with user
    read -p "Do you want to proceed with version $new_version? (y/N): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        print_warning "Version update cancelled."
        exit 0
    fi
    
    # Update version in all files
    update_version "$new_version"
    
    # Update changelog
    update_changelog "$new_version" "$release_type"
    
    # Git operations
    print_status "Creating git commit..."
    git add VERSION CHANGELOG.md composer.json package.json README.md
    git commit -m "$commit_message"
    
    # Create git tag
    print_status "Creating git tag..."
    git tag -a "v$new_version" -m "Release version $new_version"
    
    print_status "Version $new_version has been successfully created!"
    print_status ""
    
    # Provide next steps based on release type
    case $release_type in
        "dev")
            print_status "Next steps for development release:"
            echo "  1. Push to development branch: git push origin main:dev"
            echo "  2. Deploy to development environment"
            echo "  3. Team review and testing"
            echo "  4. If approved, create beta: $0 patch --beta"
            echo "  5. If issues found, create new dev: $0 patch --dev"
            ;;
        "rc")
            print_status "Next steps for release candidate:"
            echo "  1. Push to staging: git push origin main:staging"
            echo "  2. Deploy to staging environment"
            echo "  3. Final testing and review"
            echo "  4. If approved, create production release: $0 patch"
            echo "  5. If issues found, create new RC: $0 patch --rc"
            ;;
        "beta")
            print_status "Next steps for beta release:"
            echo "  1. Push to staging: git push origin main:staging"
            echo "  2. Deploy to staging environment"
            echo "  3. Gather feedback and fix issues"
            echo "  4. Create new beta or RC: $0 patch --beta"
            ;;
        *)
            print_status "Next steps for production release:"
            echo "  1. Push to production: git push origin main"
            echo "  2. Deploy to production environment"
            echo "  3. Monitor for any issues"
            ;;
    esac
    
    print_status ""
    print_status "Don't forget to push changes and tags:"
    echo "  git push origin main"
    echo "  git push origin v$new_version"
}

# Run main function with all arguments
main "$@" 