#!/bin/bash
set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CARGO_TOML="$PROJECT_ROOT/Cargo.toml"

info()    { echo -e "${CYAN}ℹ ${NC}$1"; }
success() { echo -e "${GREEN}✓ ${NC}$1"; }
warn()    { echo -e "${YELLOW}⚠ ${NC}$1"; }
error()   { echo -e "${RED}✗ ${NC}$1"; }

DRY_RUN=false
BUMP="patch"
NO_BUMP=false
for arg in "$@"; do
  case "$arg" in
    --dry-run)      DRY_RUN=true ;;
    --patch)        BUMP="patch" ;;
    --minor)        BUMP="minor" ;;
    --major)        BUMP="major" ;;
    --no-bump)      NO_BUMP=true ;;
    --help|-h)
      echo "Usage: $0 [OPTIONS]"
      echo ""
      echo "Publish l-tool to crates.io with auto version bump and SKILL.md regeneration."
      echo ""
      echo "Options:"
      echo "  --dry-run       Run all checks without actually publishing"
      echo "  --patch         Bump patch version (default: 0.1.0 -> 0.1.1)"
      echo "  --minor         Bump minor version (0.1.0 -> 0.2.0)"
      echo "  --major         Bump major version (0.1.0 -> 1.0.0)"
      echo "  --no-bump       Skip version bump (publish current version as-is)"
      echo "  -h, --help      Show this help"
      echo ""
      echo "Flow:"
      echo "  1. Check prerequisites (cargo, git)"
      echo "  2. Check Cargo.toml metadata"
      echo "  3. Ensure working tree is clean (no unstashed changes)"
      echo "  4. Bump version (default: patch)"
      echo "  5. Regenerate SKILL.md"
      echo "  6. Auto-commit version bump + SKILL.md"
      echo "  7. Run checks (check, test, clippy)"
      echo "  8. Package & publish"
      echo "  9. Git tag + push instructions"
      exit 0
      ;;
  esac
done

if [ "$NO_BUMP" = true ]; then
  BUMP=""
fi

echo ""
echo "╔══════════════════════════════════════════╗"
echo "║      l-tool — Publish to crates.io       ║"
echo "╚══════════════════════════════════════════╝"
echo ""

cd "$PROJECT_ROOT"

# ── Step 1: Prerequisites ──────────────────────────────────────────
info "Step 1: Checking prerequisites..."

if ! command -v cargo &> /dev/null; then
  error "cargo not found. Install Rust: https://rustup.rs"
  exit 1
fi
success "cargo found"

if ! command -v git &> /dev/null; then
  error "git not found"
  exit 1
fi
success "git found"

# ── Step 2: Cargo.toml metadata ────────────────────────────────────
info "Step 2: Checking Cargo.toml metadata..."

MISSING_FIELDS=()
grep -q '^description' "$CARGO_TOML" || MISSING_FIELDS+=("description")
grep -q '^license' "$CARGO_TOML"     || MISSING_FIELDS+=("license")
grep -q '^repository' "$CARGO_TOML"  || MISSING_FIELDS+=("repository")

if [ ${#MISSING_FIELDS[@]} -gt 0 ]; then
  warn "Missing recommended fields in Cargo.toml: ${MISSING_FIELDS[*]}"
  echo ""
  echo "  Add these to your [package] section:"
  for field in "${MISSING_FIELDS[@]}"; do
    case "$field" in
      description) echo '  description = "A versatile CLI tool for JS, image, PDF, git, and FFmpeg operations"' ;;
      license)     echo '  license = "GPL-3.0"' ;;
      repository)  echo '  repository = "https://github.com/learnwy/l-tool"' ;;
    esac
  done
  echo ""
  read -p "  Continue anyway? (y/N) " -n 1 -r
  echo
  [[ $REPLY =~ ^[Yy]$ ]] || exit 1
fi

# ── Step 3: Clean working tree ─────────────────────────────────────
info "Step 3: Ensuring working tree is clean..."

DIRTY=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
if [ "$DIRTY" -gt 0 ]; then
  error "Working tree is not clean. Please commit or stash your changes first."
  echo ""
  git status --short
  echo ""
  info "You can run:"
  echo "  git stash        # stash changes temporarily"
  echo "  git add -A && git commit -m 'wip'  # commit everything"
  exit 1
fi
success "Working tree is clean"

# ── Step 4: Version bump ──────────────────────────────────────────
CURRENT_VERSION=$(grep '^version' "$CARGO_TOML" | head -1 | sed 's/.*"\(.*\)".*/\1/')

if [ -n "$BUMP" ]; then
  info "Step 4: Bumping version ($BUMP)..."
  IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
  case "$BUMP" in
    patch) PATCH=$((PATCH + 1)) ;;
    minor) MINOR=$((MINOR + 1)); PATCH=0 ;;
    major) MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0 ;;
  esac
  NEW_VERSION="$MAJOR.$MINOR.$PATCH"
  info "  $CURRENT_VERSION -> $NEW_VERSION"
  sed -i '' "s/^version = \"$CURRENT_VERSION\"/version = \"$NEW_VERSION\"/" "$CARGO_TOML"
  CURRENT_VERSION="$NEW_VERSION"
  success "Version bumped to $NEW_VERSION"
else
  info "Step 4: Skipping version bump (--no-bump)"
  info "  Current version: $CURRENT_VERSION"
fi

# ── Step 5: Regenerate SKILL.md ───────────────────────────────────
info "Step 5: Regenerating SKILL.md..."

GENERATE_SKILL="$SCRIPT_DIR/generate-skill.sh"
if [ -f "$GENERATE_SKILL" ]; then
  bash "$GENERATE_SKILL"
  success "SKILL.md regenerated"
else
  warn "generate-skill.sh not found, skipping"
fi

# ── Step 6: Auto-commit ──────────────────────────────────────────
info "Step 6: Auto-committing release changes..."

CHANGED=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
if [ "$CHANGED" -gt 0 ]; then
  git add Cargo.toml Cargo.lock SKILL.md 2>/dev/null || true
  git commit -m "chore: release v$CURRENT_VERSION" --quiet
  success "Committed: chore: release v$CURRENT_VERSION"
else
  info "  No changes to commit"
fi

# ── Step 7: Run checks ───────────────────────────────────────────
info "Step 7: Running checks..."

info "  Running cargo check..."
cargo check 2>&1 | tail -1
success "  cargo check passed"

info "  Running cargo test..."
cargo test 2>&1 | tail -3
success "  cargo test passed"

info "  Running cargo clippy..."
cargo clippy -- -D warnings 2>&1 | tail -1 || warn "  clippy has warnings (non-blocking)"

# ── Step 8: Package & Publish ─────────────────────────────────────
info "Step 8: Packaging..."

cargo package --registry crates-io 2>&1 | tail -5
success "Package created successfully"

if [ "$DRY_RUN" = true ]; then
  echo ""
  success "Dry run complete! Version $CURRENT_VERSION is ready to publish."
  echo ""
  echo "  The release commit has been created locally."
  echo "  To publish for real, run:"
  echo "    $0 --no-bump"
  echo ""
  echo "  To undo the release commit:"
  echo "    git reset --soft HEAD~1"
  exit 0
fi

info "Step 9: Publishing to crates.io..."
echo ""
warn "About to publish l-tool v$CURRENT_VERSION to crates.io"
warn "This action is IRREVERSIBLE for this version number."
read -p "  Proceed? (y/N) " -n 1 -r
echo

if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  info "Aborted. The release commit is still in your local history."
  info "To undo: git reset --soft HEAD~1"
  exit 0
fi

cargo publish --registry crates-io 2>&1

# ── Step 10: Tag ──────────────────────────────────────────────────
info "Step 10: Creating git tag..."

git tag "v$CURRENT_VERSION"
success "Tagged v$CURRENT_VERSION"

echo ""
success "🎉 l-tool v$CURRENT_VERSION published to crates.io!"
echo ""
echo "  Install: cargo install l-tool"
echo "  View:    https://crates.io/crates/l-tool"
echo ""
info "Don't forget to push:"
echo "  git push && git push --tags"
