#!/bin/bash

# script/suggest-version: Suggest next semantic version based on commit analysis
#
# Analyzes conventional commits since last release and suggests appropriate
# version bump (MAJOR.MINOR.PATCH) based on commit types.
#
# Usage:
#   ./scripts/release/suggest-version [--from TAG]
#
# Examples:
#   ./scripts/release/suggest-version
#   ./scripts/release/suggest-version --from v0.2.0

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR/../.."

# shellcheck source=scripts/.lib/output.sh
source "$SCRIPT_DIR/../.lib/output.sh"

# Parse arguments
FROM_TAG="${2:-}"

# Get current version from manifest.json
MANIFEST="custom_components/tibber_prices/manifest.json"
if [[ ! -f $MANIFEST ]]; then
    die "Manifest file not found: $MANIFEST"
fi

# Require jq for JSON parsing
require_command "jq" "apt-get install jq (or brew install jq)"

MANIFEST_VERSION=$(jq -r '.version' "$MANIFEST")
MANIFEST_TAG="v${MANIFEST_VERSION}"

# Get latest version tag
if [[ -z $FROM_TAG ]]; then
    FROM_TAG=$(git tag -l 'v*.*.*' --sort=-version:refname | head -1)
    if [[ -z $FROM_TAG ]]; then
        die "No version tags found"
    fi
fi

# Check if manifest version already has a tag
if git rev-parse "$MANIFEST_TAG" >/dev/null 2>&1; then
    # Manifest version is already tagged - analyze from that tag
    FROM_TAG="$MANIFEST_TAG"
    log_info "manifest.json version $MANIFEST_VERSION already tagged as $MANIFEST_TAG"
    echo ""
fi

log_header "Analyzing commits since $FROM_TAG"
echo ""

# Parse current version (from the tag we're analyzing from)
CURRENT_VERSION="${FROM_TAG#v}"
MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1)
MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2)
PATCH=$(echo "$CURRENT_VERSION" | cut -d. -f3)

printf "Current released version: %bv%s.%s.%s%b\n" "$BOLD" "$MAJOR" "$MINOR" "$PATCH" "$NC"
if [[ $MANIFEST_VERSION != "$CURRENT_VERSION" ]]; then
    log_warning "Manifest.json version: $MANIFEST_VERSION (not yet tagged)"
fi
echo ""

# Analyze commits (exclude version bump commits)
COMMITS=$(git log "$FROM_TAG"..HEAD --format="%s" --no-merges | grep -v "^chore(release):" || true)

if [[ -z $COMMITS ]]; then
    log_warning "No new commits since last release"

    # Check if manifest.json needs to be tagged
    if [[ $MANIFEST_VERSION != "$CURRENT_VERSION" ]]; then
        echo ""
        log_info "Manifest.json has version $MANIFEST_VERSION but no tag exists yet."
        echo "Create tag with:"
        echo "  git tag -a v${MANIFEST_VERSION} -m \"Release ${MANIFEST_VERSION}\""
        echo "  git push origin v${MANIFEST_VERSION}"
    fi
    exit 0
fi

# Count commit types (using grep -c with || true to handle zero matches)
BREAKING_COUNT=$(echo "$COMMITS" | grep -c "^[^:]*!:" || true)
FEAT_COUNT=$(echo "$COMMITS" | grep -c -E "^feat(\(.+\))?:" || true)
FIX_COUNT=$(echo "$COMMITS" | grep -c -E "^fix(\(.+\))?:" || true)
REFACTOR_COUNT=$(echo "$COMMITS" | grep -c -E "^refactor(\(.+\))?:" || true)
DOCS_COUNT=$(echo "$COMMITS" | grep -c -E "^docs(\(.+\))?:" || true)
OTHER_COUNT=$(echo "$COMMITS" | grep -v -c -E "^(feat|fix|refactor|docs)(\(.+\))?:" || true)

# Check for breaking changes in commit messages or Impact sections
BREAKING_IN_BODY=$(git log "$FROM_TAG"..HEAD --format="%b" --no-merges | grep -c -i "BREAKING CHANGE:" || true)
TOTAL_BREAKING=$((BREAKING_COUNT + BREAKING_IN_BODY))

printf "%bCommit Analysis:%b\n" "$BOLD" "$NC"
echo ""
if [ "$TOTAL_BREAKING" -gt 0 ]; then
    printf "  %b⚠ Breaking changes:%b %s\n" "$RED" "$NC" "$TOTAL_BREAKING"
fi
printf "  %b✨ New features:%b %s\n" "$GREEN" "$NC" "$FEAT_COUNT"
printf "  %b🐛 Bug fixes:%b %s\n" "$BLUE" "$NC" "$FIX_COUNT"
if [ "$REFACTOR_COUNT" -gt 0 ]; then
    printf "  %b🔧 Refactorings:%b %s\n" "$YELLOW" "$NC" "$REFACTOR_COUNT"
fi
if [ "$DOCS_COUNT" -gt 0 ]; then
    printf "  📚 Documentation: %s\n" "$DOCS_COUNT"
fi
if [ "$OTHER_COUNT" -gt 0 ]; then
    printf "  📦 Other: %s\n" "$OTHER_COUNT"
fi
echo ""

# Determine version bump
SUGGESTED_MAJOR=$MAJOR
SUGGESTED_MINOR=$MINOR
SUGGESTED_PATCH=$PATCH

if [ "$TOTAL_BREAKING" -gt 0 ]; then
    # Before v1.0.0: Breaking changes bump minor
    # After v1.0.0: Breaking changes bump major
    if [ "$MAJOR" -eq 0 ]; then
        SUGGESTED_MINOR=$((MINOR + 1))
        SUGGESTED_PATCH=0
        BUMP_TYPE="MINOR (breaking changes in 0.x)"
        BUMP_REASON="Breaking changes detected (before v1.0.0 → bump minor)"
    else
        SUGGESTED_MAJOR=$((MAJOR + 1))
        SUGGESTED_MINOR=0
        SUGGESTED_PATCH=0
        BUMP_TYPE="MAJOR (breaking)"
        BUMP_REASON="Breaking changes detected"
    fi
elif [ "$FEAT_COUNT" -gt 0 ]; then
    SUGGESTED_MINOR=$((MINOR + 1))
    SUGGESTED_PATCH=0
    BUMP_TYPE="MINOR (features)"
    BUMP_REASON="New features added"
elif [ "$FIX_COUNT" -gt 0 ]; then
    SUGGESTED_PATCH=$((PATCH + 1))
    BUMP_TYPE="PATCH (fixes)"
    BUMP_REASON="Bug fixes only"
else
    SUGGESTED_PATCH=$((PATCH + 1))
    BUMP_TYPE="PATCH (other)"
    BUMP_REASON="Documentation/refactoring changes"
fi

SUGGESTED_VERSION="v${SUGGESTED_MAJOR}.${SUGGESTED_MINOR}.${SUGGESTED_PATCH}"

printf "%b%bSuggested Version: %s%b\n" "$BOLD" "$GREEN" "$SUGGESTED_VERSION" "$NC"
printf "  Bump type: %s\n" "$BUMP_TYPE"
printf "  Reason: %s\n" "$BUMP_REASON"
echo ""

# Show alternative versions
printf "%bAlternative Versions:%b\n" "$BOLD" "$NC"
printf "  %bMAJOR:%b v%s.0.0 (if you want to release v1.0.0 or have breaking changes)\n" "$YELLOW" "$NC" "$((MAJOR + 1))"
printf "  %bMINOR:%b v%s.%s.0 (if adding features)\n" "$GREEN" "$NC" "$MAJOR" "$((MINOR + 1))"
printf "  %bPATCH:%b v%s.%s.%s (if only fixes/docs)\n" "$BLUE" "$NC" "$MAJOR" "$MINOR" "$((PATCH + 1))"
echo ""

# Show preview command
printf "%bPreview Release Notes:%b\n" "$BOLD" "$NC"
echo "  ./scripts/release/generate-notes $FROM_TAG HEAD"
echo ""
printf "%bCreate Release:%b\n" "$BOLD" "$NC"
echo "  ./scripts/release/prepare ${SUGGESTED_MAJOR}.${SUGGESTED_MINOR}.${SUGGESTED_PATCH}"
echo ""

# Show warning if breaking changes detected
if [ "$TOTAL_BREAKING" -gt 0 ]; then
    printf "%b%b⚠ WARNING: Breaking changes detected!%b\n" "$RED" "$BOLD" "$NC"
    printf "%bMake sure to document migration steps in release notes.%b\n" "$RED" "$NC"
    echo ""
fi

# Show note about pre-1.0 versioning
if [ "$MAJOR" -eq 0 ]; then
    printf "%bNote: Pre-1.0 versioning (0.x.y)%b\n" "$YELLOW" "$NC"
    echo "  - Breaking changes bump MINOR (0.x.0)"
    echo "  - Features bump MINOR (0.x.0)"
    echo "  - Fixes bump PATCH (0.0.x)"
    echo "  - After v1.0.0: Breaking changes bump MAJOR (x.0.0)"
fi
