#!/bin/bash

###############################################################################
# 发布到官方 NPM 脚本
# Publish to Official NPM Registry Script
#
# 用途: 将项目发布到官方 npmjs.org
# Purpose: Publish the project to official npmjs.org
#
# 使用方法 / Usage:
#   ./scripts/publish-to-npmjs.sh [version_type]
#   
#   version_type: patch | minor | major | prerelease (可选)
#   
# 示例 / Examples:
#   ./scripts/publish-to-npmjs.sh patch
#   ./scripts/publish-to-npmjs.sh minor
#   ./scripts/publish-to-npmjs.sh
###############################################################################

set -e

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

# Emoji
CHECK="✅"
CROSS="❌"
WARN="⚠️"
INFO="ℹ️"
ROCKET="🚀"

###############################################################################
# Helper Functions
###############################################################################

print_header() {
    echo ""
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}$1${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
}

print_success() {
    echo -e "${GREEN}${CHECK} $1${NC}"
}

print_error() {
    echo -e "${RED}${CROSS} $1${NC}"
}

print_warning() {
    echo -e "${YELLOW}${WARN} $1${NC}"
}

print_info() {
    echo -e "${BLUE}${INFO} $1${NC}"
}

confirm() {
    read -p "$1 [y/N] " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        return 1
    fi
    return 0
}

###############################################################################
# Welcome
###############################################################################

echo -e "${BLUE}"
cat << "EOF"
╔═══════════════════════════════════════════════════════════╗
║                                                           ║
║     发布到官方 NPM / Publish to Official NPM             ║
║                                                           ║
╚═══════════════════════════════════════════════════════════╝
EOF
echo -e "${NC}"

###############################################################################
# Step 1: 检查 NPM 登录
###############################################################################

print_header "Step 1: 检查 NPM 登录状态 / Check NPM Login"

print_info "Checking npmjs.org login status..."

if npm whoami &> /dev/null; then
    NPM_USER=$(npm whoami)
    print_success "已登录 / Logged in as: $NPM_USER"
    
    # 显示 npm 账号信息
    NPM_EMAIL=$(npm profile get email 2>/dev/null || echo "N/A")
    print_info "Email: $NPM_EMAIL"
else
    print_error "未登录到 npmjs.org / Not logged in to npmjs.org"
    echo ""
    print_warning "请先登录到 npmjs.org / Please login first"
    echo ""
    echo "如果已有账号 / If you have an account:"
    echo "  npm login"
    echo ""
    echo "如果还没有账号 / If you don't have an account:"
    echo "  1. 访问 / Visit: https://www.npmjs.com/signup"
    echo "  2. 注册账号 / Sign up"
    echo "  3. 运行 / Run: npm login"
    echo ""
    exit 1
fi

# 检查包权限
PACKAGE_NAME=$(node -p "require('./package.json').name")
print_info "检查包权限 / Checking package permissions: $PACKAGE_NAME"

if npm view $PACKAGE_NAME &> /dev/null; then
    print_warning "包已存在 / Package already exists on npm"
    
    # 检查是否有发布权限
    OWNERS=$(npm owner ls $PACKAGE_NAME 2>/dev/null || echo "")
    if echo "$OWNERS" | grep -q "$NPM_USER"; then
        print_success "你有发布权限 / You have publish permission"
    else
        print_error "你没有发布权限 / You don't have publish permission"
        echo ""
        echo "当前拥有者 / Current owners:"
        echo "$OWNERS"
        echo ""
        echo "请联系包的拥有者添加你为协作者 / Please contact the package owner to add you as a collaborator"
        exit 1
    fi
else
    print_info "这是新包，首次发布 / This is a new package, first publish"
fi

###############################################################################
# Step 2: 确认发布信息
###############################################################################

print_header "Step 2: 确认发布信息 / Confirm Publish Info"

# 检查 package.json 是否有未提交的修改
if git diff --quiet HEAD -- package.json; then
    print_success "package.json 状态正常 / package.json is clean"
else
    print_warning "⚠️  package.json 有未提交的修改 / package.json has uncommitted changes"
    
    WORKING_VERSION=$(node -p "require('./package.json').version")
    GIT_VERSION=$(git show HEAD:package.json 2>/dev/null | node -p "JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8')).version" 2>/dev/null || echo "unknown")
    
    echo ""
    echo "Git HEAD 版本 / Git HEAD version:     $GIT_VERSION"
    echo "工作目录版本 / Working directory:      $WORKING_VERSION"
    echo ""
    
    if ! confirm "检测到版本不一致，是否恢复到 Git 版本？/ Version mismatch detected, restore to Git version?"; then
        print_warning "继续使用工作目录版本 / Continue with working directory version"
    else
        git checkout HEAD -- package.json
        print_success "已恢复 package.json / Restored package.json"
        # 重新同步 version.ts
        yarn genversion &> /dev/null
    fi
fi

CURRENT_VERSION=$(node -p "require('./package.json').version")
PACKAGE_DESC=$(node -p "require('./package.json').description")

echo "包名称 / Package: $PACKAGE_NAME"
echo "当前版本 / Current version: $CURRENT_VERSION"
echo "描述 / Description: $PACKAGE_DESC"
echo "发布到 / Publish to: https://registry.npmjs.org"
echo ""

###############################################################################
# Step 3: 选择版本类型
###############################################################################

VERSION_TYPE=$1

if [ -z "$VERSION_TYPE" ]; then
    print_header "Step 3: 选择版本类型 / Select Version Type"
    
    echo "1) patch      - Bug 修复 (${CURRENT_VERSION} -> $(npm version patch --no-git-tag-version --dry-run 2>/dev/null | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' || echo 'x.x.x'))"
    echo "2) minor      - 新功能 (${CURRENT_VERSION} -> $(npm version minor --no-git-tag-version --dry-run 2>/dev/null | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' || echo 'x.x.x'))"
    echo "3) major      - 破坏性变更 (${CURRENT_VERSION} -> $(npm version major --no-git-tag-version --dry-run 2>/dev/null | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+' || echo 'x.x.x'))"
    echo "4) prerelease - 预发布版本"
    echo "5) 跳过版本更新 / Skip version update"
    echo ""
    echo -n "请选择 [1-5]: "
    read -r choice
    
    case $choice in
        1) VERSION_TYPE="patch" ;;
        2) VERSION_TYPE="minor" ;;
        3) VERSION_TYPE="major" ;;
        4) VERSION_TYPE="prerelease" ;;
        5) VERSION_TYPE="" ;;
        *)
            echo "Invalid choice, using 'patch'"
            VERSION_TYPE="patch"
            ;;
    esac
fi

###############################################################################
# Step 4: 运行测试
###############################################################################

print_header "Step 4: 运行测试 / Run Tests"

print_info "Running linter..."
if yarn test:lint; then
    print_success "Linter passed"
else
    print_error "Linter failed"
    if ! confirm "测试失败，是否继续？ / Tests failed, continue anyway?"; then
        exit 1
    fi
fi

print_info "Running format check (skipping .md files)..."
# 只检查代码文件格式，跳过 Markdown 文件
if yarn prettier --check "src/**/*.{ts,tsx,js,jsx}" "scripts/**/*.js" --ignore-unknown 2>/dev/null; then
    print_success "Format check passed (Markdown files skipped)"
else
    print_warning "Code format issues found (Markdown files skipped)"
    print_info "提示：运行 'yarn prettier --write' 可以自动修复 / Tip: Run 'yarn prettier --write' to auto-fix"
    if ! confirm "代码格式有问题，是否继续？ / Code format issues, continue anyway?"; then
        exit 1
    fi
fi

print_info "Running type check..."
if yarn test:types; then
    print_success "Type check passed"
else
    print_error "Type check failed"
    if ! confirm "类型检查失败，是否继续？ / Type check failed, continue anyway?"; then
        exit 1
    fi
fi

###############################################################################
# Step 5: 清理和构建
###############################################################################

print_header "Step 5: 构建项目 / Build Project"

print_info "Cleaning old build..."
if [ -d "lib" ]; then
    rm -rf lib/
    print_success "Cleaned"
fi

print_info "Building project..."
# yarn prepare 已优化：只包含 genversion 和 bob build，不含 typedoc
if yarn prepare; then
    print_success "Build completed (docs generation skipped)"
    
    # 显示构建大小
    BUILD_SIZE=$(du -sh lib/ 2>/dev/null | cut -f1 || echo "N/A")
    print_info "Build size: $BUILD_SIZE"
else
    print_error "Build failed"
    exit 1
fi

###############################################################################
# Step 6: 更新版本
###############################################################################

if [ -n "$VERSION_TYPE" ]; then
    print_header "Step 6: 更新版本 / Update Version"
    
    print_info "Updating version: $VERSION_TYPE"
    
    # 检查 Git 工作目录状态
    if ! git diff-index --quiet HEAD --; then
        print_warning "Git working directory is not clean"
        print_warning "There are uncommitted changes"
        
        if ! confirm "继续更新版本？/ Continue version update anyway?"; then
            print_error "请先提交更改 / Please commit your changes first"
            echo ""
            echo "运行 / Run:"
            echo "  git status"
            echo "  git add ."
            echo "  git commit -m 'your commit message'"
            exit 1
        fi
        
        # 添加 --force 和 --no-git-tag-version 标志
        print_warning "Using --force and --no-git-tag-version flags"
        FORCE_FLAG="--force --no-git-tag-version"
    else
        FORCE_FLAG=""
    fi
    
    if [ "$VERSION_TYPE" = "prerelease" ]; then
        npm version prerelease --preid=beta $FORCE_FLAG
    else
        npm version $VERSION_TYPE $FORCE_FLAG
    fi
    
    NEW_VERSION=$(node -p "require('./package.json').version")
    print_success "Version updated: $CURRENT_VERSION -> $NEW_VERSION"
    
    # 自动提交 package.json
    if [ -n "$FORCE_FLAG" ]; then
        print_warning "版本已更新但未创建 Git tag / Version updated but Git tag not created"
        print_info "你需要手动提交和打标签 / You need to commit and tag manually"
    else
        # 只有在没有使用 --force 标志时才自动提交（即工作目录是干净的）
        print_info "Auto-committing package.json..."
        
        if git add package.json; then
            print_success "Added: package.json"
            
            COMMIT_MSG="chore: bump version to ${NEW_VERSION}"
            if git commit -m "$COMMIT_MSG"; then
                print_success "Committed: $COMMIT_MSG"
                
                # npm version 命令已经创建了 tag，所以不需要再创建
                TAG_NAME="v${NEW_VERSION}"
                print_success "Git tag created by npm: $TAG_NAME"
            else
                print_warning "Commit failed (file may be unchanged)"
            fi
        else
            print_warning "Failed to add package.json"
        fi
    fi
else
    NEW_VERSION=$CURRENT_VERSION
    print_info "Skipping version update"
fi

###############################################################################
# Step 7: 预览发布内容
###############################################################################

print_header "Step 7: 预览发布内容 / Preview Publish"

print_info "Running npm publish --dry-run..."
echo ""

npm publish --dry-run --access public

echo ""
print_success "Dry run completed"
print_warning "请检查上面的文件列表 / Please review the files list above"

###############################################################################
# Step 8: 最终确认
###############################################################################

print_header "Step 8: 最终确认 / Final Confirmation"

echo -e "${YELLOW}"
echo "即将发布到官方 NPM / About to publish to official NPM:"
echo ""
echo "  包名称 / Package:  $PACKAGE_NAME"
echo "  版本 / Version:    $NEW_VERSION"
echo "  Registry:          https://registry.npmjs.org"
echo "  Public URL:        https://www.npmjs.com/package/$PACKAGE_NAME"
echo ""
echo -e "${NC}"

if ! confirm "${ROCKET} 确认发布到 npmjs.org? / Confirm publish to npmjs.org?"; then
    print_warning "发布已取消 / Publish cancelled"
    
    if [ "$NEW_VERSION" != "$CURRENT_VERSION" ]; then
        print_info "版本已更新，请手动回滚或稍后发布"
        print_info "Version updated, please rollback manually or publish later"
    fi
    
    exit 0
fi

###############################################################################
# Step 9: 发布到 NPM
###############################################################################

print_header "Step 9: 发布到 NPM / Publish to NPM"

print_info "Publishing to npmjs.org..."

if npm publish --access public; then
    print_success "Successfully published to npmjs.org!"
else
    print_error "Publish failed"
    exit 1
fi

###############################################################################
# Step 10: 验证发布
###############################################################################

print_header "Step 10: 验证发布 / Verify Publish"

print_info "Waiting for npm to update..."
sleep 5

if npm view $PACKAGE_NAME@$NEW_VERSION &> /dev/null; then
    print_success "Package verified on npm!"
    
    echo ""
    echo -e "${GREEN}${ROCKET}${ROCKET}${ROCKET} 发布成功！/ Published Successfully! ${ROCKET}${ROCKET}${ROCKET}${NC}"
    echo ""
    echo "包信息 / Package Info:"
    echo "  名称 / Name:     $PACKAGE_NAME"
    echo "  版本 / Version:  $NEW_VERSION"
    echo "  查看 / View:     https://www.npmjs.com/package/$PACKAGE_NAME"
    echo ""
    echo "安装命令 / Install Command:"
    echo "  npm install $PACKAGE_NAME@$NEW_VERSION"
    echo "  yarn add $PACKAGE_NAME@$NEW_VERSION"
    echo ""
    echo "下一步 / Next Steps:"
    
    # 提示需要推送到 Git
    if [ "$NEW_VERSION" != "$CURRENT_VERSION" ]; then
        echo "  🔴 推送到 Git / Push to Git (Required):"
        CURRENT_BRANCH=$(git branch --show-current)
        echo "     git push origin $CURRENT_BRANCH"
        echo "     git push origin --tags"
        echo ""
    fi
    
    echo "  ✅ 创建 GitHub Release / Create GitHub Release"
    echo "     https://github.com/appzung/react-native-code-push/releases/new?tag=v$NEW_VERSION"
    echo ""
    echo "  ✅ 更新文档 / Update Documentation"
    echo "  ✅ 通知团队和用户 / Notify Team and Users"
    echo ""
else
    print_warning "无法立即验证包，可能需要等待几分钟"
    print_warning "Cannot verify package immediately, may need to wait a few minutes"
    echo ""
    echo "请手动检查 / Please check manually:"
    echo "  https://www.npmjs.com/package/$PACKAGE_NAME"
fi

echo ""
if [ "$NEW_VERSION" != "$CURRENT_VERSION" ]; then
    echo -e "${YELLOW}⚠️  注意：别忘了推送到 Git！/ Don't forget to push to Git!${NC}"
    echo ""
fi
echo -e "${GREEN}感谢使用！/ Thank you!${NC}"
echo ""

