# climaybe — PR Update (Optional Preview Package)
# Creates a Shopify preview theme on PR update, renames it with PR number,
# and posts preview/customize links back to the PR.

name: PR Update

on:
  pull_request:
    types: [opened, synchronize, reopened]
    branches: [main, staging, develop, 'staging-*', 'live-*']

jobs:
  filter:
    runs-on: ubuntu-latest
    outputs:
      theme: ${{ steps.paths.outputs.theme }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: paths
        with:
          filters: |
            theme:
              - 'assets/**'
              - 'blocks/**'
              - 'config/**'
              - 'layout/**'
              - 'locales/**'
              - 'sections/**'
              - 'snippets/**'
              - 'templates/**'
              - '_scripts/**'
              - '_styles/**'
              - 'shopify.theme.toml'
              - 'stores/**'

  extract-pr-number:
    needs: [filter]
    if: needs.filter.outputs.theme == 'true'
    uses: ./.github/workflows/reusable-extract-pr-number.yml

  validate-environment:
    needs: [filter]
    if: needs.filter.outputs.theme == 'true'
    runs-on: ubuntu-latest
    outputs:
      store_alias: ${{ steps.resolve.outputs.store_alias }}
      store_alias_secret: ${{ steps.resolve.outputs.store_alias_secret }}
      preview_targets_json: ${{ steps.resolve.outputs.preview_targets_json }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Resolve preview store targets from source branch
        id: resolve
        env:
          BASE_REF: ${{ github.event.pull_request.base.ref }}
          HEAD_REF: ${{ github.event.pull_request.head.ref }}
        run: |
          node <<'NODE' >>"$GITHUB_OUTPUT"
          const fs = require('fs');
          const cfg = JSON.parse(fs.readFileSync('climaybe.config.json', 'utf8'));
          const stores = cfg?.stores || {};
          const keys = Object.keys(stores);
          const baseRef = process.env.BASE_REF || '';
          const headRef = process.env.HEAD_REF || '';
          const branchRef = headRef || baseRef;
          const isMulti = keys.length > 1;
          const isStagingLive =
            branchRef && (/^staging-/.test(branchRef) || /^live-/.test(branchRef));

          const aliasToSecret = (a) => String(a).toUpperCase().replace(/-/g, '_');
          const normalizeDomain = (v) =>
            String(v || '')
              .toLowerCase()
              .replace(/^https?:\/\//, '')
              .replace(/\/.*$/, '');

          let targets = [];
          if (isMulti && !isStagingLive) {
            targets = keys.map((alias) => ({ alias, alias_secret: aliasToSecret(alias) }));
          } else if (isStagingLive) {
            let a = branchRef.replace(/^staging-/, '').replace(/^live-/, '');
            targets = [{ alias: a, alias_secret: aliasToSecret(a) }];
          } else {
            const defaultStoreNorm = normalizeDomain(cfg?.default_store);
            let alias = '';
            if (defaultStoreNorm) {
              for (const [k, d] of Object.entries(stores)) {
                if (normalizeDomain(d) === defaultStoreNorm) {
                  alias = k;
                  break;
                }
              }
            }
            if (!alias) alias = keys[0] || '';
            if (!alias && cfg?.default_store) {
              const sub = normalizeDomain(cfg.default_store).split('.')[0] || 'default';
              alias = sub.replace(/[^a-z0-9-]/g, '-').replace(/-+/g, '-') || 'default';
            }
            if (!alias) alias = 'default';
            targets = [{ alias, alias_secret: aliasToSecret(alias) }];
          }

          if (targets.length === 0 || targets.some((t) => !t.alias)) {
            console.error('Could not resolve store targets from climaybe.config.json');
            process.exit(1);
          }

          console.log('preview_targets_json<<PT_JSON');
          console.log(JSON.stringify(targets));
          console.log('PT_JSON');
          console.log(`store_alias=${targets[0].alias}`);
          console.log(`store_alias_secret=${targets[0].alias_secret}`);
          NODE

  validate-secrets-per-store:
    needs: [validate-environment]
    strategy:
      fail-fast: false
      matrix:
        include: ${{ fromJson(needs.validate-environment.outputs.preview_targets_json) }}
    runs-on: ubuntu-latest
    steps:
      - name: Require Shopify URL + theme token for this store
        env:
          SHOPIFY_STORE_URL_SCOPED: ${{ secrets[format('SHOPIFY_STORE_URL_{0}', matrix.alias_secret)] }}
          SHOPIFY_THEME_ACCESS_TOKEN_SCOPED: ${{ secrets[format('SHOPIFY_THEME_ACCESS_TOKEN_{0}', matrix.alias_secret)] }}
          SHOPIFY_STORE_URL_DEFAULT: ${{ secrets.SHOPIFY_STORE_URL }}
          SHOPIFY_THEME_ACCESS_TOKEN_DEFAULT: ${{ secrets.SHOPIFY_THEME_ACCESS_TOKEN }}
        run: |
          SHOPIFY_STORE_URL="${SHOPIFY_STORE_URL_SCOPED:-$SHOPIFY_STORE_URL_DEFAULT}"
          SHOPIFY_THEME_ACCESS_TOKEN="${SHOPIFY_THEME_ACCESS_TOKEN_SCOPED:-$SHOPIFY_THEME_ACCESS_TOKEN_DEFAULT}"
          if [ -z "$SHOPIFY_STORE_URL" ] || [ -z "$SHOPIFY_THEME_ACCESS_TOKEN" ]; then
            echo "Missing SHOPIFY_* for ${{ matrix.alias }} (secret suffix ${{ matrix.alias_secret }})."
            exit 1
          fi
          echo "Shopify credentials OK for ${{ matrix.alias }}"

  cleanup-themes:
    needs: [validate-environment, extract-pr-number, validate-secrets-per-store]
    strategy:
      fail-fast: false
      matrix:
        include: ${{ fromJson(needs.validate-environment.outputs.preview_targets_json) }}
    uses: ./.github/workflows/reusable-cleanup-themes.yml
    with:
      cleanup_mode: by_pr
      pr_number: ${{ needs.extract-pr-number.outputs.pr_number }}
      store_alias_secret: ${{ matrix.alias_secret }}
    secrets: inherit

  publish-preview-store:
    needs: [validate-environment, extract-pr-number, cleanup-themes]
    strategy:
      fail-fast: false
      matrix:
        include: ${{ fromJson(needs.validate-environment.outputs.preview_targets_json) }}
    uses: ./.github/workflows/reusable-publish-pr-preview-store.yml
    with:
      pr_number: ${{ needs.extract-pr-number.outputs.pr_number }}
      store_alias: ${{ matrix.alias }}
      store_alias_secret: ${{ matrix.alias_secret }}
    secrets: inherit

  comment-on-pr:
    needs: [publish-preview-store, extract-pr-number, validate-environment]
    uses: ./.github/workflows/reusable-comment-on-pr.yml
    with:
      theme_id: ${{ needs.publish-preview-store.outputs.theme_id }}
      share_output: ${{ needs.publish-preview-store.outputs.share_output }}
      pr_number: ${{ needs.extract-pr-number.outputs.pr_number_unpadded }}
      store_alias: ${{ needs.validate-environment.outputs.store_alias }}
      store_alias_secret: ${{ needs.validate-environment.outputs.store_alias_secret }}
      use_preview_fragments: 'true'
    secrets: inherit
