#!/bin/bash

# script/prepare: Prepare a new release by bumping version and creating tag
#
# Validates version format, updates manifest.json, commits with conventional
# commit format, and creates annotated git tag. You control when to push.
#
# Usage:
#   ./scripts/release/prepare [VERSION|--suggest]
#
# Examples:
#   ./scripts/release/prepare --suggest   # Show version suggestion
#   ./scripts/release/prepare 0.3.0       # Bump to version 0.3.0
#   ./scripts/release/prepare 1.0.0       # Bump to version 1.0.0
#   ./scripts/release/prepare 0.25.0b0    # Bump to beta version 0.25.0b0

set -euo pipefail

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

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

# Check if --suggest or no argument
if [[ ${1:-} == --suggest ]] || [[ -z ${1:-} ]]; then
    "$SCRIPT_DIR/suggest-version"

    if [[ -z ${1:-} ]]; then
        echo ""
        log_warning "Provide version number as argument:"
        echo "  ./scripts/release/prepare X.Y.Z"
        exit 0
    fi
    exit 0
fi

# Check if we have uncommitted changes
if ! git diff-index --quiet HEAD --; then
    die "You have uncommitted changes. Please commit or stash them first."
fi

# Parse version argument
VERSION="${1:-}"
if [[ -z $VERSION ]]; then
    die "No version specified.\n\nUsage: $0 VERSION\n\nExamples:\n  $0 0.3.0      # Bump to version 0.3.0\n  $0 1.0.0      # Bump to version 1.0.0\n  $0 0.25.0b0   # Bump to beta version 0.25.0b0"
fi

# Strip 'v' prefix if present
VERSION="${VERSION#v}"

# Validate version format (X.Y.Z or X.Y.ZbN for prerelease/beta)
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+(b[0-9]+)?$'; then
    die "Invalid version format: $VERSION\nExpected format: X.Y.Z or X.Y.ZbN (e.g., 0.3.0, 1.0.0, 0.25.0b0)"
fi

IS_PRERELEASE=false
if [[ $VERSION =~ b[0-9]+$ ]]; then
    IS_PRERELEASE=true
    log_header "Documentation guardrail"
    log_step "Detected beta/prerelease version ($VERSION)"
    log_step "Skip Docusaurus versioning: leave docs on 'next'"
    log_step "Only version docs on final stable releases"
fi

TAG="v$VERSION"
MANIFEST="custom_components/tibber_prices/manifest.json"

# Check if manifest.json exists
if [[ ! -f $MANIFEST ]]; then
    die "Manifest file not found: $MANIFEST"
fi

# Check if tag already exists (locally or remotely)
if git rev-parse "$TAG" >/dev/null 2>&1; then
    die "Tag $TAG already exists locally\\nTo remove it: git tag -d $TAG"
fi

if git ls-remote --tags origin | grep -q "refs/tags/${TAG}$"; then
    die "Tag $TAG already exists on remote"
fi

# Get current version
CURRENT_VERSION=$(jq -r '.version' "$MANIFEST")
log_info "Current version: ${BOLD}${CURRENT_VERSION}${NC}"
log_info "New version: ${BOLD}${VERSION}${NC}"
echo ""

# Update manifest.json
log_header "Updating $MANIFEST"
require_command "jq" "apt-get install jq (or brew install jq)"

# Create backup
cp "$MANIFEST" "$MANIFEST.backup"

# Update version with jq
if ! jq ".version = \"$VERSION\"" "$MANIFEST" >"$MANIFEST.tmp"; then
    mv "$MANIFEST.backup" "$MANIFEST"
    die "Failed to update manifest.json"
fi

mv "$MANIFEST.tmp" "$MANIFEST"
rm "$MANIFEST.backup"

log_success "Updated manifest.json"

# Stage and commit
log_header "Creating commit"
git add "$MANIFEST"
git commit -m "chore(release): bump version to $VERSION"
log_success "Created commit"

# Create annotated tag
log_header "Creating tag $TAG"
git tag -a "$TAG" -m "chore(release): version $VERSION"
log_success "Created tag $TAG"

# Show preview
echo ""
log_separator
printf "%b%s Release %s prepared successfully!%b\n" "$BOLD$GREEN" "$SPARKLES" "$VERSION" "$NC"
log_separator
echo ""
printf "%bReview the changes:%b\n" "$BOLD" "$NC"
git log -1 --stat
echo ""
printf "%bReview the tag:%b\n" "$BOLD" "$NC"
git show "$TAG" --no-patch
echo ""
log_separator
printf "%bNext steps:%b\n" "$BOLD" "$NC"
echo ""
printf "  %b%s To push and trigger release:%b\n" "$GREEN" "$CHECK" "$NC"
printf "    %bgit push origin main %s%b\n" "$BOLD" "$TAG" "$NC"
echo ""
printf "  %b%s To abort and undo:%b\n" "$RED" "$CROSS" "$NC"
printf "    git reset --hard HEAD~1    # Undo commit\n"
printf "    git tag -d %s            # Delete tag\n" "$TAG"
echo ""
printf "%bWhat happens after push:%b\n" "$BOLD" "$NC"
log_step "Both commit and tag are pushed to GitHub"
log_step "CI/CD detects the new tag"
log_step "Release notes are generated automatically"
log_step "GitHub release is created"
log_separator
