#!/bin/bash
#
# do the necessary things to build and publish python project
#

# Status tracking: 0=pending, 1=done, 2=failed, 3=unavailable (N/A)
declare -a STATUS=(0 0 0 0 0 0 0 0)

# Check prerequisites and mark unavailable steps
check_prerequisites() {
    # Check if README.org exists for step 1
    if [ ! -f README.org ]; then
        STATUS[0]=3
    fi
    # Check if .bumpversion.cfg exists for step 5
    if [ ! -f .bumpversion.cfg ]; then
        STATUS[4]=3
    fi
}

# Run prerequisite check at startup
check_prerequisites

# Clear any stale publish timestamp to ensure '8' standalone is immediate
rm -f /tmp/jusfltuls_publish_time

# Action functions
action_1_convert_readme() {
    if [ -f README.org ]; then
        echo "📝 Converting README.org to README.md..."
        if pandoc README.org -o README.md; then
            STATUS[0]=1
            echo "✅ README.org converted to README.md"
        else
            STATUS[0]=2
            echo "❌ Failed to convert README.org"
        fi
    else
        echo "⚠️  README.org not found - step not applicable"
        STATUS[0]=3
    fi
}

action_2_git_check() {
    git diff --quiet && git diff --cached --quiet && [ -z "$(git ls-files --others --exclude-standard)" ]

    if [ "$?" != "0" ]; then
        echo "x... git is not clean... committing automatically"
        sleep 1
        if git commit -a -m "debug with automatic commit"; then
            STATUS[1]=1
            echo "✓ Git auto-commit successful"
        else
            STATUS[1]=2
            echo "✗ Git auto-commit failed"
        fi
    else
        echo "i... git is clean"
        STATUS[1]=1
    fi
}

action_3_git_pull() {
    # Get current branch name
    BRANCH=$(git rev-parse --abbrev-ref HEAD)
    if [ -z "$BRANCH" ]; then
        echo "✗ Could not determine current branch"
        STATUS[2]=2
        return
    fi
    echo "📋 Current branch: $BRANCH"

    echo "⬇️  Pulling from origin/$BRANCH..."
    if git pull origin "$BRANCH"; then
        echo "✓ Git pull successful"
        echo "⬇️  Pulling tags from origin..."
        if git pull --tags origin "$BRANCH"; then
            STATUS[2]=1
            echo "✅ Git pull and tags updated"
        else
            STATUS[2]=2
            echo "❌ Failed to pull tags"
        fi
    else
        STATUS[2]=2
        echo "❌ Failed to pull from origin"
    fi
}

action_4_clean_dist() {
    if [ -d "dist" ]; then
        echo "i... cleaning dist/"
        if rm -f dist/*; then
            STATUS[3]=1
            echo "✓ dist/ cleaned"
        else
            STATUS[3]=2
            echo "✗ Failed to clean dist/"
        fi
    else
        echo "✗ dist/ doesn't exist, cannot clean"
        STATUS[3]=2
    fi
}

action_5_bump_version() {
    if [ ! -f .bumpversion.cfg ]; then
        echo "⚠️  .bumpversion.cfg not found - step not applicable"
        STATUS[4]=3
        return
    fi

    # Get current version before bump
    OLD_VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | sed 's/.*=\s*"\?\([^"]*\)"\?.*/\1/')
    echo "📋 Current version: $OLD_VERSION"

    echo "🔖 Bumping version (patch)..."
    if bumpversion patch; then
        # Get new version after bump
        NEW_VERSION=$(grep -E '^version\s*=' pyproject.toml | head -1 | sed 's/.*=\s*"\?\([^"]*\)"\?.*/\1/')
        echo "📋 New version: $NEW_VERSION"
        # Save new version to a temp file for later use
        echo "$NEW_VERSION" > /tmp/jusfltuls_new_version

        echo "📤 Pushing to origin with tags..."
        if git push origin --all && git push origin --tags; then
            STATUS[4]=1
            echo "✅ Version bumped and pushed"
        else
            STATUS[4]=2
            echo "❌ Failed to push to origin"
        fi
    else
        STATUS[4]=2
        echo "❌ Failed to bump version"
    fi
}

action_6_build() {
    echo "i... running uv build"
    if uv build; then
        STATUS[5]=1
        echo "✓ Build successful"
    else
        STATUS[5]=2
        echo "✗ Build failed"
    fi
}

action_7_publish() {
    echo "i... publishing to PyPI"
    tok=$(cat ~/.pypirc | grep pass | awk '{print$3}')
    if [ -z "$tok" ]; then
        STATUS[6]=2
        echo "✗ Failed to read token from ~/.pypirc"
        return
    fi

    if uv publish --username __token__ --password "$tok"; then
        STATUS[6]=1
        echo "✓ Published to PyPI"
        # Save timestamp for bullet 8 countdown logic
        date +%s > /tmp/jusfltuls_publish_time
    else
        STATUS[6]=2
        echo "✗ Failed to publish to PyPI"
    fi
}

action_8_install() {
    local run_all_mode=false
    if [ "$1" = "--run-all" ]; then
        run_all_mode=true
    fi

    echo "i... installing package with uv tool"

    # Get package name from pyproject.toml
    PACKAGE_NAME=$(grep -E '^name\s*=' pyproject.toml | head -1 | sed 's/.*=\s*"\([^"]*\)".*/\1/')
    if [ -z "$PACKAGE_NAME" ]; then
        echo "✗ Could not determine package name from pyproject.toml"
        STATUS[7]=2
        return
    fi
    echo "📦 Package name: $PACKAGE_NAME"

    # Check if we should do countdown (only if bullet 7 completed within last 10 seconds)
    DO_COUNTDOWN=false
    # Only do countdown if bullet 7 was actually completed (STATUS[6] == 1)
    if [ "${STATUS[6]}" -eq 1 ] && [ -f /tmp/jusfltuls_publish_time ]; then
        PUBLISH_TIME=$(cat /tmp/jusfltuls_publish_time)
        CURRENT_TIME=$(date +%s)
        TIME_DIFF=$((CURRENT_TIME - PUBLISH_TIME))
        if [ $TIME_DIFF -le 13 ]; then
            DO_COUNTDOWN=true
        fi
    fi

    if [ "$DO_COUNTDOWN" = true ]; then
        # In run-all mode, wait 9 seconds; otherwise wait 13 seconds
        if [ "$run_all_mode" = true ]; then
            echo "i... waiting first few seconds ... 9"
            sleep 1
            echo "i... waiting first few seconds ... 8"
            sleep 1
            echo "i... waiting first few seconds ... 7"
            sleep 1
            echo "i... waiting first few seconds ... 6"
            sleep 1
            echo "i... waiting first few seconds ... 5"
            sleep 1
            echo "i... waiting first few seconds ... 4"
            sleep 1
            echo "i... waiting first few seconds ... 3"
            sleep 1
            echo "i... waiting first few seconds ... 2"
            sleep 1
            echo "i... waiting first few seconds ... 1"
            sleep 1
            echo "i... waiting first few seconds ... 0"
            sleep 1
        else
            echo "i... waiting first few seconds ... 12"
            sleep 1
            echo "i... waiting first few seconds ... 11"
            sleep 1
            echo "i... waiting first few seconds ... 10"
            sleep 1
            echo "i... waiting first few seconds ... 9"
            sleep 1
            echo "i... waiting first few seconds ... 8"
            sleep 1
            echo "i... waiting first few seconds ... 7"
            sleep 1
            echo "i... waiting first few seconds ... 6"
            sleep 1
            echo "i... waiting first few seconds ... 5"
            sleep 1
            echo "i... waiting first few seconds ... 4"
            sleep 1
            echo "i... waiting first few seconds ... 3"
            sleep 1
            echo "i... waiting first few seconds ... 2"
            sleep 1
            echo "i... waiting first few seconds ... 1"
            sleep 1
            echo "i... waiting first few seconds ... 0"
            sleep 1
        fi
    fi

    # Function to attempt installation
    attempt_install() {
        if uv tool install "$PACKAGE_NAME" --upgrade; then
            return 0
        else
            return 1
        fi
    }

    # Function to verify installation - captures mismatch message to stderr
    verify_install() {
        echo "🔍 Verifying installed version..."
        if [ -f /tmp/jusfltuls_new_version ]; then
            EXPECTED_VERSION=$(cat /tmp/jusfltuls_new_version)
            INSTALLED_VERSION=$("$PACKAGE_NAME" --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown")
            echo "📋 Expected version: $EXPECTED_VERSION"
            echo "📋 Installed version: $INSTALLED_VERSION"
            if [ "$INSTALLED_VERSION" = "$EXPECTED_VERSION" ]; then
                echo "✅ Version verification successful!"
                return 0
            else
                STATUS[7]=2
                # Output mismatch message to both stdout and stderr for capture
                echo "❌ Version mismatch! Package may not be available on PyPI yet." | tee /dev/stderr
                return 1
            fi
        else
            echo "ℹ️  No version file found, skipping verification"
            return 0
        fi
    }

    # First installation attempt
    if attempt_install; then
        STATUS[7]=1
        echo "✓ Package installed/upgraded"
        # Capture verify_install output to check for version mismatch
        VERIFY_OUTPUT=$(verify_install 2>&1)
        VERIFY_RESULT=$?
        echo "$VERIFY_OUTPUT"

        # In run-all mode, if version mismatch, wait 5 seconds and retry
        if [ "$run_all_mode" = true ] && [ $VERIFY_RESULT -ne 0 ]; then
            if echo "$VERIFY_OUTPUT" | grep -q "Version mismatch"; then
                echo ""
                echo "i... version mismatch detected, waiting 5 seconds before retry..."
                sleep 5
                echo "i... retrying installation..."
                echo ""

                if attempt_install; then
                    STATUS[7]=1
                    echo "✓ Package installed/upgraded (on retry)"
                    verify_install
                else
                    STATUS[7]=2
                    echo "✗ Failed to install package on retry"
                fi
            fi
        fi
    else
        STATUS[7]=2
        echo "✗ Failed to install package"

        # In run-all mode, wait 5 more seconds and retry
        if [ "$run_all_mode" = true ]; then
            echo ""
            echo "i... waiting 5 more seconds before retry..."
            sleep 5
            echo "i... retrying installation..."
            echo ""

            if attempt_install; then
                STATUS[7]=1
                echo "✓ Package installed/upgraded (on retry)"
                verify_install
            else
                STATUS[7]=2
                echo "✗ Failed to install package on retry"
            fi
        fi
    fi
}

# Display menu
show_menu() {
    clear
    # symbols: 0=pending, 1=done, 2=failed, 3=unavailable
    local symbols=("☐" "☑" "☒" "⊘")
    local colors=("\033[90m" "\033[32m" "\033[31m" "\033[33m")
    local reset="\033[0m"

    # Count completed, failed, and unavailable
    local completed=0
    local failed=0
    local unavailable=0
    for s in "${STATUS[@]}"; do
        [ "$s" -eq 1 ] && ((completed++))
        [ "$s" -eq 2 ] && ((failed++))
        [ "$s" -eq 3 ] && ((unavailable++))
    done

    # Progress bar (only count non-unavailable items)
    local total=${#STATUS[@]}
    local applicable=$((total - unavailable))
    local progress=0
    if [ $applicable -gt 0 ]; then
        progress=$((completed * 100 / applicable))
    fi
    local filled=$((progress * 30 / 100))
    local empty=$((30 - filled))
    local bar=""
    for ((i=0; i<filled; i++)); do bar="${bar}█"; done
    for ((i=0; i<empty; i++)); do bar="${bar}░"; done

    # Use printf consistently for all output to avoid alignment issues
    printf "╔════════════════════════════════════════════════════════════════╗\n"
    printf "║     📦 DISTCHECK - Python Package Publishing Workflow          ║\n"
    printf "╚════════════════════════════════════════════════════════════════╝\n"
    printf "\n"
    printf "┌────────────────────────────────────────────────────────────────┐\n"
    printf "│  WORKFLOW STEPS:                                               │\n"
    printf "├────┬──────────┬────────────────────────────────────────────────┤\n"
    printf "│ %s │ ${colors[${STATUS[0]}]}%-8s${reset}   │ %-46s   │\n" " 1" "${symbols[${STATUS[0]}]}" "Convert README.org → README.md"
    printf "│ %s │ ${colors[${STATUS[1]}]}%-8s${reset}   │ %-46s │\n" " 2" "${symbols[${STATUS[1]}]}" "Check git status / auto-commit"
    printf "│ %s │ ${colors[${STATUS[2]}]}%-8s${reset}   │ %-46s │\n" " 3" "${symbols[${STATUS[2]}]}" "Git GPOAT (pull + tags)"
    printf "│ %s │ ${colors[${STATUS[3]}]}%-8s${reset}   │ %-46s │\n" " 4" "${symbols[${STATUS[3]}]}" "Clean dist/ directory"
    printf "│ %s │ ${colors[${STATUS[4]}]}%-8s${reset}   │ %-46s │\n" " 5" "${symbols[${STATUS[4]}]}" "Bump version (patch) and push tags"
    printf "│ %s │ ${colors[${STATUS[5]}]}%-8s${reset}   │ %-46s │\n" " 6" "${symbols[${STATUS[5]}]}" "Build package with uv"
    printf "│ %s │ ${colors[${STATUS[6]}]}%-8s${reset}   │ %-46s │\n" " 7" "${symbols[${STATUS[6]}]}" "Publish to PyPI"
    printf "│ %s │ ${colors[${STATUS[7]}]}%-8s${reset}   │ %-46s │\n" " 8" "${symbols[${STATUS[7]}]}" "Install/upgrade with uv tool"
    printf "├────┴──────────┴────────────────────────────────────────────────┤\n"
    printf "│  PROGRESS: [%s] %3d%%               │\n" "$bar" "$progress"
    printf "│         ☑ %d done  ☒ %d failed  ⊘ %d N/A                          │\n" "$completed" "$failed" "$unavailable"
    printf "├────────────────────────────────────────────────────────────────┤\n"
    printf "│  COMMANDS: [a] Run all  [r] Reset  [q] Quit  [1-8] Step        │\n"
    printf "└────────────────────────────────────────────────────────────────┘\n"
    printf "\n"
    printf "Press a key: "
}

# Run all actions in order
run_all() {
    action_1_convert_readme
    echo ""
    action_2_git_check
    echo ""
    action_3_git_pull
    echo ""
    action_4_clean_dist
    echo ""
    action_5_bump_version
    echo ""
    action_6_build
    echo ""
    action_7_publish
    echo ""
    action_8_install --run-all
}

# Reset all status
reset_status() {
    STATUS=(0 0 0 0 0 0 0 0)
    check_prerequisites
}

# Main loop
while true; do
    show_menu
    read -n 1 -r key
    echo ""
    echo ""

    case $key in
        1) action_1_convert_readme ;;
        2) action_2_git_check ;;
        3) action_3_git_pull ;;
        4) action_4_clean_dist ;;
        5) action_5_bump_version ;;
        6) action_6_build ;;
        7) action_7_publish ;;
        8) action_8_install ;;
        a|A)
            echo "🚀 Running all steps in sequence..."
            echo ""
            run_all
            echo ""
            echo "Press any key to continue..."
            read -n 1 -r
            ;;
        r|R)
            reset_status
            echo "🔄 All status reset to pending"
            sleep 1
            continue
            ;;
        q|Q)
            echo "👋 Exiting..."
            exit 0
            ;;
        *)
            echo "❌ Invalid option: '$key'"
            sleep 1
            continue
            ;;
    esac

    echo ""
    echo "Press any key to continue..."
    read -n 1 -r
done
