name: Sync Components from Main Repository

on:
    workflow_dispatch:
        inputs:
            sync_directories:
                description: "Directories to sync (comma-separated)"
                required: false
                default: "components,hooks,utils,styles"
                type: string
            sync_mode:
                description: "Sync mode"
                required: false
                default: "all"
                type: choice
                options:
                    - all
                    - existing-only

jobs:
    sync-components:
        runs-on: ubuntu-latest
        permissions:
            contents: write
            pull-requests: write

        steps:
            - name: Checkout repository
              uses: actions/checkout@v4
              with:
                  token: ${{ secrets.GITHUB_TOKEN }}
                  fetch-depth: 0

            - name: Setup Node.js
              uses: actions/setup-node@v4
              with:
                  node-version: "18"

            - name: Configure git
              run: |
                  git config --global user.name "github-actions[bot]"
                  git config --global user.email "github-actions[bot]@users.noreply.github.com"

            - name: Fetch main repository and get commit info
              id: fetch-main-repo
              run: |
                  echo "Fetching main repository..."

                  # Create a temporary directory for cloning
                  mkdir -p /tmp/main-repo
                  cd /tmp/main-repo

                  # Clone the main repository
                  git clone https://github.com/untitleduico/react.git .

                  # Get latest commit info
                  LATEST_COMMIT_HASH=$(git rev-parse HEAD)
                  LATEST_COMMIT_SHORT=$(git rev-parse --short HEAD)
                  LATEST_COMMIT_MESSAGE=$(git log -1 --pretty=format:"%s")
                  LATEST_COMMIT_AUTHOR=$(git log -1 --pretty=format:"%an")
                  LATEST_COMMIT_DATE=$(git log -1 --pretty=format:"%ci")

                  echo "LATEST_COMMIT_HASH=$LATEST_COMMIT_HASH" >> $GITHUB_ENV
                  echo "LATEST_COMMIT_SHORT=$LATEST_COMMIT_SHORT" >> $GITHUB_ENV
                  echo "LATEST_COMMIT_MESSAGE=$LATEST_COMMIT_MESSAGE" >> $GITHUB_ENV
                  echo "LATEST_COMMIT_AUTHOR=$LATEST_COMMIT_AUTHOR" >> $GITHUB_ENV
                  echo "LATEST_COMMIT_DATE=$LATEST_COMMIT_DATE" >> $GITHUB_ENV

                  echo "Latest commit: $LATEST_COMMIT_SHORT - $LATEST_COMMIT_MESSAGE"

                  # Get the directory structure (main repo has directories at root level, not in src/)
                  # Exclude demo and story files
                  find components hooks utils styles -type f ! -name "*.demo.tsx" ! -name "*.story.tsx" ! -name "*.stories.tsx" 2>/dev/null | sort > /tmp/main-repo-files.txt || echo "Some directories may not exist"

                  echo "Files to sync:"
                  cat /tmp/main-repo-files.txt

            - name: Get last synced commit
              id: get-last-sync
              run: |
                  cd $GITHUB_WORKSPACE

                  # Check if we have a previous sync record
                  if [ -f ".github/last-sync-commit" ] && [ -s ".github/last-sync-commit" ]; then
                    # Read the first line and trim whitespace, ignore comments
                    LAST_SYNC_COMMIT=$(head -n 1 .github/last-sync-commit | xargs | grep -v '^#' || echo "")
                    
                    if [ -n "$LAST_SYNC_COMMIT" ] && [ "$LAST_SYNC_COMMIT" != "" ]; then
                      echo "LAST_SYNC_COMMIT=$LAST_SYNC_COMMIT" >> $GITHUB_ENV
                      echo "Found previous sync commit: $LAST_SYNC_COMMIT"
                    else
                      echo "LAST_SYNC_COMMIT=" >> $GITHUB_ENV
                      echo "Sync file exists but no valid commit hash found"
                    fi
                  else
                    echo "LAST_SYNC_COMMIT=" >> $GITHUB_ENV
                    echo "No previous sync record found"
                  fi

            - name: Get commits since last sync
              id: get-commits-since-sync
              run: |
                  cd /tmp/main-repo

                  if [ -n "$LAST_SYNC_COMMIT" ]; then
                    echo "Getting commits since $LAST_SYNC_COMMIT..."
                    
                    # Get commit log since last sync
                    git log --oneline "$LAST_SYNC_COMMIT".."$LATEST_COMMIT_HASH" > /tmp/commits-since-sync.txt || echo "Could not get commit range"
                    
                    # Count commits
                    COMMIT_COUNT=$(wc -l < /tmp/commits-since-sync.txt)
                    echo "COMMIT_COUNT=$COMMIT_COUNT" >> $GITHUB_ENV
                    
                    echo "Commits since last sync ($COMMIT_COUNT):"
                    cat /tmp/commits-since-sync.txt
                  else
                    echo "COMMIT_COUNT=unknown" >> $GITHUB_ENV
                    echo "No previous sync - this is the first sync"
                    echo "First sync - syncing from latest commit" > /tmp/commits-since-sync.txt
                  fi

            - name: Create sync branch
              run: |
                  cd $GITHUB_WORKSPACE
                  BRANCH_NAME="sync/$(date +%Y-%m-%d-%H%M%S)-$LATEST_COMMIT_SHORT"
                  echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV

                  # Delete branch if it exists locally
                  git branch -D "$BRANCH_NAME" 2>/dev/null || true

                  # Delete branch if it exists remotely
                  git push origin --delete "$BRANCH_NAME" 2>/dev/null || true

                  # Create fresh branch
                  git checkout -b "$BRANCH_NAME"
                  echo "Created branch: $BRANCH_NAME"

            - name: Sync files from main repository
              run: |
                  cd /tmp/main-repo

                  # Read the sync directories from input
                  IFS=',' read -ra DIRS <<< "${{ github.event.inputs.sync_directories }}"

                  # Create sync summary file
                  echo "# Sync Summary" > /tmp/sync-summary.md
                  echo "" >> /tmp/sync-summary.md

                  for dir in "${DIRS[@]}"; do
                    dir=$(echo "$dir" | xargs) # trim whitespace
                    echo "## Syncing $dir directory" >> /tmp/sync-summary.md
                    
                    # Main repo has directories at root level, target repo has them in src/
                    if [ -d "$dir" ]; then
                      # Create directory in target repo if it doesn't exist
                      mkdir -p "$GITHUB_WORKSPACE/src/$dir"
                      
                      # Find all files in the directory from main repo, excluding demo and story files
                      find "$dir" -type f ! -name "*.demo.tsx" ! -name "*.story.tsx" ! -name "*.stories.tsx" | while read -r file; do
                        target_file="$GITHUB_WORKSPACE/src/$file"
                        
                        # Check sync mode
                        if [ "${{ github.event.inputs.sync_mode }}" = "existing-only" ]; then
                          # Only process if target file already exists
                          if [ ! -f "$target_file" ]; then
                            echo "Skipping new file: $file (existing-only mode)"
                            continue
                          fi
                        fi
                        
                        echo "Processing $file..."
                        
                        # Copy file content and process it
                        content=$(cat "$file")
                        
                        # Remove "use client" directive if present (including double newlines after it)
                        # This handles both double quotes and single quotes, with optional semicolon
                        processed_content=$(echo "$content" | sed -E '
                          /^"use client";?\s*$/{
                            N
                            N
                            s/"use client";?\s*\n\s*\n//
                          }
                          /^'\''use client'\'';?\s*$/{
                            N
                            N
                            s/'\''use client'\'';?\s*\n\s*\n//
                          }
                        ')
                        
                        # Target file goes in src/ directory
                        target_dir=$(dirname "$target_file")
                        mkdir -p "$target_dir"
                        
                        # Write processed content to target file
                        echo "$processed_content" > "$target_file"
                        
                        echo "- src/$file" >> /tmp/sync-summary.md
                      done
                      
                      # Log skipped files for transparency
                      DEMO_STORY_SKIPPED=$(find "$dir" -type f \( -name "*.demo.tsx" -o -name "*.story.tsx" -o -name "*.stories.tsx" \) | wc -l)
                      
                      if [ "${{ github.event.inputs.sync_mode }}" = "existing-only" ]; then
                        # Count new files that were skipped
                        NEW_FILES_SKIPPED=0
                        find "$dir" -type f ! -name "*.demo.tsx" ! -name "*.story.tsx" ! -name "*.stories.tsx" | while read -r file; do
                          target_file="$GITHUB_WORKSPACE/src/$file"
                          if [ ! -f "$target_file" ]; then
                            NEW_FILES_SKIPPED=$((NEW_FILES_SKIPPED + 1))
                          fi
                        done
                        
                        if [ "$NEW_FILES_SKIPPED" -gt 0 ]; then
                          echo "Skipped $NEW_FILES_SKIPPED new files (existing-only mode)"
                          echo "- Skipped $NEW_FILES_SKIPPED new files (existing-only mode)" >> /tmp/sync-summary.md
                        fi
                      fi
                      
                      if [ "$DEMO_STORY_SKIPPED" -gt 0 ]; then
                        echo "Skipped $DEMO_STORY_SKIPPED demo/story files"
                        echo "- Skipped $DEMO_STORY_SKIPPED demo/story files" >> /tmp/sync-summary.md
                      fi
                    else
                      echo "Directory $dir not found in main repository" >> /tmp/sync-summary.md
                    fi
                  done

            - name: Check for changes
              id: check-changes
              run: |
                  cd $GITHUB_WORKSPACE
                  if git diff --quiet; then
                    echo "changes=false" >> $GITHUB_OUTPUT
                    echo "No changes detected"
                  else
                    echo "changes=true" >> $GITHUB_OUTPUT
                    echo "Changes detected"
                  fi

            - name: Generate detailed diff summary
              if: steps.check-changes.outputs.changes == 'true'
              run: |
                  cd $GITHUB_WORKSPACE

                  echo "# Component sync changes" > /tmp/pr-description.md
                  echo "" >> /tmp/pr-description.md
                  echo "This PR synchronizes components from the main repository [untitleduico/react](https://github.com/untitleduico/react)." >> /tmp/pr-description.md
                  echo "" >> /tmp/pr-description.md

                  # Add commits since last sync section
                  echo "## 📝 Commits since last sync" >> /tmp/pr-description.md
                  echo "" >> /tmp/pr-description.md
                  if [ -n "$LAST_SYNC_COMMIT" ] && [ "$COMMIT_COUNT" != "unknown" ]; then
                    if [ "$COMMIT_COUNT" -gt 0 ]; then
                      echo "**$COMMIT_COUNT new commits** from [\`$LAST_SYNC_COMMIT\`](https://github.com/untitleduico/react/commit/$LAST_SYNC_COMMIT) to [\`$LATEST_COMMIT_SHORT\`](https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH):" >> /tmp/pr-description.md
                      echo "" >> /tmp/pr-description.md
                      echo "<details>" >> /tmp/pr-description.md
                      echo "<summary>View commit history</summary>" >> /tmp/pr-description.md
                      echo "" >> /tmp/pr-description.md
                      while IFS= read -r commit_line; do
                        if [ -n "$commit_line" ]; then
                          commit_hash=$(echo "$commit_line" | cut -d' ' -f1)
                          commit_msg=$(echo "$commit_line" | cut -d' ' -f2-)
                          echo "- [\`$commit_hash\`](https://github.com/untitleduico/react/commit/$commit_hash) $commit_msg" >> /tmp/pr-description.md
                        fi
                      done < /tmp/commits-since-sync.txt
                      echo "" >> /tmp/pr-description.md
                      echo "</details>" >> /tmp/pr-description.md
                    else
                      echo "✅ **Repository is up to date** - no new commits since last sync [\`$LAST_SYNC_COMMIT\`](https://github.com/untitleduico/react/commit/$LAST_SYNC_COMMIT)" >> /tmp/pr-description.md
                    fi
                  else
                    echo "🎉 **First sync** - syncing from latest commit [\`$LATEST_COMMIT_SHORT\`](https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH)" >> /tmp/pr-description.md
                    echo "" >> /tmp/pr-description.md
                    echo "**Latest commit**: $LATEST_COMMIT_MESSAGE" >> /tmp/pr-description.md
                    echo "**Author**: $LATEST_COMMIT_AUTHOR" >> /tmp/pr-description.md
                    echo "**Date**: $LATEST_COMMIT_DATE" >> /tmp/pr-description.md
                  fi
                  echo "" >> /tmp/pr-description.md

                  echo "## 📁 Modified files" >> /tmp/pr-description.md
                  echo "" >> /tmp/pr-description.md

                  # Get file statistics
                  TOTAL_FILES=$(git diff --name-only | wc -l)
                  echo "**$TOTAL_FILES files modified**" >> /tmp/pr-description.md
                  echo "" >> /tmp/pr-description.md

                  # List all changed files
                  git diff --name-only | while read -r file; do
                    if [ -n "$file" ]; then
                      echo "- \`$file\`" >> /tmp/pr-description.md
                    fi
                  done
                  echo "" >> /tmp/pr-description.md

                  echo "## 🔧 Sync details" >> /tmp/pr-description.md
                  echo "" >> /tmp/pr-description.md
                  echo "- **Source repository**: [untitleduico/react](https://github.com/untitleduico/react)" >> /tmp/pr-description.md
                  echo "- **Latest commit**: [\`$LATEST_COMMIT_SHORT\`](https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH)" >> /tmp/pr-description.md
                  echo "- **Sync date**: $(date -u '+%Y-%m-%d %H:%M:%S UTC')" >> /tmp/pr-description.md
                  echo "- **Directories synced**: ${{ github.event.inputs.sync_directories }}" >> /tmp/pr-description.md
                  echo "- **Sync mode**: ${{ github.event.inputs.sync_mode }}" >> /tmp/pr-description.md
                  echo "- **Automated processing**: Removed \`\"use client\";\` directives, excluded demo/story files" >> /tmp/pr-description.md
                  echo "" >> /tmp/pr-description.md
                  echo "---" >> /tmp/pr-description.md
                  echo "*This PR was automatically generated by the sync-components workflow.*" >> /tmp/pr-description.md

            - name: Store sync commit record
              if: steps.check-changes.outputs.changes == 'true'
              run: |
                  cd $GITHUB_WORKSPACE

                  # Create .github directory if it doesn't exist
                  mkdir -p .github

                  # Store the latest commit hash for next sync
                  echo "$LATEST_COMMIT_HASH" > .github/last-sync-commit

                  echo "Stored sync commit: $LATEST_COMMIT_HASH"

            - name: Commit changes
              if: steps.check-changes.outputs.changes == 'true'
              run: |
                  cd $GITHUB_WORKSPACE
                  git add .

                  # Create commit message
                  if [ -n "$LAST_SYNC_COMMIT" ] && [ "$COMMIT_COUNT" != "unknown" ] && [ "$COMMIT_COUNT" -gt 0 ]; then
                    COMMIT_MSG="sync: Update components from main repository ($COMMIT_COUNT commits)

                  Synced from: $LAST_SYNC_COMMIT..$LATEST_COMMIT_SHORT
                  Latest commit: $LATEST_COMMIT_MESSAGE
                  Directories: ${{ github.event.inputs.sync_directories }}
                  Source: https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH
                  Automated processing: Removed 'use client' directives"
                  else
                    COMMIT_MSG="sync: Initial sync from main repository

                  Latest commit: $LATEST_COMMIT_SHORT - $LATEST_COMMIT_MESSAGE
                  Author: $LATEST_COMMIT_AUTHOR
                  Directories: ${{ github.event.inputs.sync_directories }}
                  Source: https://github.com/untitleduico/react/commit/$LATEST_COMMIT_HASH
                  Automated processing: Removed 'use client' directives"
                  fi

                  git commit -m "$COMMIT_MSG"

            - name: Push changes and create PR
              if: steps.check-changes.outputs.changes == 'true'
              env:
                  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
              run: |
                  cd $GITHUB_WORKSPACE
                  git push origin "$BRANCH_NAME"

                  # Create PR title based on sync type
                  if [ -n "$LAST_SYNC_COMMIT" ] && [ "$COMMIT_COUNT" != "unknown" ] && [ "$COMMIT_COUNT" -gt 0 ]; then
                    PR_TITLE="🔄 Sync components ($COMMIT_COUNT commits) → $LATEST_COMMIT_SHORT"
                  else
                    PR_TITLE="🎉 Initial sync from main repository → $LATEST_COMMIT_SHORT"
                  fi

                  # Create PR using GitHub CLI
                  gh pr create \
                    --title "$PR_TITLE" \
                    --body-file /tmp/pr-description.md \
                    --head "$BRANCH_NAME" \
                    --base main

            - name: Output results
              run: |
                  if [ "${{ steps.check-changes.outputs.changes }}" == "true" ]; then
                    echo "✅ Sync completed successfully. PR created."
                    echo "Branch: $BRANCH_NAME"
                  else
                    echo "ℹ️ No changes detected. Repository is already in sync."
                  fi
