name: POEditor Diff & Sync

on:
  push:
    branches: [ master ]
  workflow_dispatch: {}

concurrency:
  group: poeditor-sync
  cancel-in-progress: false

jobs:
  sync-translations:
    runs-on: ubuntu-latest
    timeout-minutes: 20

    steps:
      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.x'

      - name: Install jq
        run: sudo apt-get update && sudo apt-get install -y jq

      - name: Extract source strings from codebase
        env:
          API_TOKEN: ${{ secrets.POEDITOR_API_TOKEN }}
          PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }}
        run: |
          set -euo pipefail

          echo "::group::Extracting strings from QML files"
          python3 translations/extract_translations.py
          echo "::endgroup::"

          echo "::group::Checking for changes in en.json"
          if [[ -f "translations/en.json" ]]; then
            jq -S . "translations/en.json" > /tmp/en_new.json
            if [[ -f "translations/en.json.orig" ]]; then
              jq -S . "translations/en.json.orig" > /tmp/en_old.json
            else
              git show HEAD:translations/en.json > /tmp/en_old.json 2>/dev/null || echo "[]" > /tmp/en_old.json
              jq -S . /tmp/en_old.json > /tmp/en_old.json.tmp && mv /tmp/en_old.json.tmp /tmp/en_old.json
            fi

            if diff -q /tmp/en_new.json /tmp/en_old.json >/dev/null 2>&1; then
              echo "No changes in source strings"
              echo "source_changed=false" >> "$GITHUB_OUTPUT"
            else
              echo "Detected changes in source strings"
              echo "source_changed=true" >> "$GITHUB_OUTPUT"

              echo "::group::Uploading source strings to POEditor"
              RESP=$(curl -sS -X POST https://api.poeditor.com/v2/projects/upload \
                -F api_token="$API_TOKEN" \
                -F id="$PROJECT_ID" \
                -F updating="terms" \
                -F file=@"translations/en.json")

              STATUS=$(echo "$RESP" | jq -r '.response.status')
              if [[ "$STATUS" != "success" ]]; then
                echo "::warning::POEditor upload failed: $RESP"
              else
                TERMS_ADDED=$(echo "$RESP" | jq -r '.result.terms.added // 0')
                TERMS_UPDATED=$(echo "$RESP" | jq -r '.result.terms.updated // 0')
                TERMS_DELETED=$(echo "$RESP" | jq -r '.result.terms.deleted // 0')
                echo "Terms added: $TERMS_ADDED, updated: $TERMS_UPDATED, deleted: $TERMS_DELETED"
              fi
              echo "::endgroup::"
            fi
          else
            echo "::warning::translations/en.json not found"
            echo "source_changed=false" >> "$GITHUB_OUTPUT"
          fi
          echo "::endgroup::"
        id: extract

      - name: Commit and push source strings
        if: steps.extract.outputs.source_changed == 'true'
        run: |
          set -euo pipefail

          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

          git add translations/en.json translations/template.json
          git commit -m "i18n: update source strings from codebase"

          for attempt in 1 2 3; do
            if git push; then
              echo "Successfully pushed source string updates"
              exit 0
            fi
            echo "Push attempt $attempt failed, pulling and retrying..."
            git pull --rebase
            sleep $((attempt*2))
          done

          echo "Failed to push after retries" >&2
          exit 1

      - name: Export and update translations from POEditor
        env:
          API_TOKEN: ${{ secrets.POEDITOR_API_TOKEN }}
          PROJECT_ID: ${{ secrets.POEDITOR_PROJECT_ID }}
        run: |
          set -euo pipefail

          LANGUAGES=(
            "ja:translations/poexports/ja.json"
            "zh-Hans:translations/poexports/zh_CN.json"
            "pt-br:translations/poexports/pt.json"
          )

          ANY_CHANGED=false

          for lang_pair in "${LANGUAGES[@]}"; do
            IFS=':' read -r PO_LANG REPO_FILE <<< "$lang_pair"

            echo "::group::Processing $PO_LANG"

            RESP=$(curl -sS -X POST https://api.poeditor.com/v2/projects/export \
              -d api_token="$API_TOKEN" \
              -d id="$PROJECT_ID" \
              -d language="$PO_LANG" \
              -d type="key_value_json")

            STATUS=$(echo "$RESP" | jq -r '.response.status')
            if [[ "$STATUS" != "success" ]]; then
              echo "POEditor export request failed for $PO_LANG: $RESP" >&2
              continue
            fi

            URL=$(echo "$RESP" | jq -r '.result.url')
            if [[ -z "$URL" || "$URL" == "null" ]]; then
              echo "No export URL returned for $PO_LANG" >&2
              continue
            fi

            curl -sS -L "$URL" -o "/tmp/po_export_${PO_LANG}.json"
            jq -S . "/tmp/po_export_${PO_LANG}.json" > "/tmp/po_export_${PO_LANG}.norm.json"

            if [[ -f "$REPO_FILE" ]]; then
              jq -S . "$REPO_FILE" > "/tmp/repo_${PO_LANG}.norm.json" || echo "{}" > "/tmp/repo_${PO_LANG}.norm.json"
            else
              echo "{}" > "/tmp/repo_${PO_LANG}.norm.json"
            fi

            if diff -q "/tmp/po_export_${PO_LANG}.norm.json" "/tmp/repo_${PO_LANG}.norm.json" >/dev/null; then
              echo "No changes for $PO_LANG"
            else
              echo "Detected changes for $PO_LANG"
              mkdir -p "$(dirname "$REPO_FILE")"
              cp "/tmp/po_export_${PO_LANG}.norm.json" "$REPO_FILE"
              ANY_CHANGED=true
            fi

            echo "::endgroup::"
          done

          echo "any_changed=$ANY_CHANGED" >> "$GITHUB_OUTPUT"
        id: export

      - name: Commit and push translation updates
        if: steps.export.outputs.any_changed == 'true'
        run: |
          set -euo pipefail

          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

          git add translations/poexports/*.json
          git commit -m "i18n: update translations"

          for attempt in 1 2 3; do
            if git push; then
              echo "Successfully pushed translation updates"
              exit 0
            fi
            echo "Push attempt $attempt failed, pulling and retrying..."
            git pull --rebase
            sleep $((attempt*2))
          done

          echo "Failed to push after retries" >&2
          exit 1
