name: Triage icon issue

on:
  issues:
    types: [opened, edited, reopened]

permissions:
  issues: write
  contents: read

concurrency:
  group: triage-issue-${{ github.event.issue.number }}
  cancel-in-progress: true

jobs:
  triage:
    name: Auto-label & comment
    runs-on: ubuntu-latest
    env:
      TRIAGE_OUTPUT: ${{ github.workspace }}/triage.json
    steps:
      - uses: actions/checkout@v6
        with:
          sparse-checkout: |
            src/data/icons.json
            .github/scripts
          sparse-checkout-cone-mode: false

      - uses: actions/setup-node@v6
        with:
          node-version: "20"

      - name: Run triage
        id: triage
        run: node .github/scripts/triage-issue.mjs

      - name: Apply labels and comment
        uses: actions/github-script@v9
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const fs = require('fs');
            const path = process.env.TRIAGE_OUTPUT;
            const decision = JSON.parse(fs.readFileSync(path, 'utf8'));
            if (decision.skipped) {
              core.info(`triage skipped: ${decision.reason}`);
              return;
            }
            const { owner, repo } = context.repo;
            const issue_number = decision.issue;

            // Labels this workflow owns - cleared on every run so edits do
            // not leave stale state (e.g. triage:needs-svg sticking around
            // after the submitter pasted an SVG).
            const isManagedLabel = (name) =>
              name === "icons" ||
              name === "icon-request" ||
              name === "icon-update" ||
              name === "duplicate" ||
              name.startsWith("triage:") ||
              name.startsWith("category:");

            const issue = await github.rest.issues.get({ owner, repo, issue_number });
            const desired = new Set(decision.labels);
            for (const lbl of issue.data.labels || []) {
              const name = typeof lbl === "string" ? lbl : lbl.name;
              if (isManagedLabel(name) && !desired.has(name)) {
                try {
                  await github.rest.issues.removeLabel({ owner, repo, issue_number, name });
                } catch (e) {
                  if (e.status !== 404) throw e;
                }
              }
            }

            // Idempotent label creation
            const labelColors = {
              "icons": "f9d0c4",
              "icon-request": "1d76db",
              "icon-update": "fbca04",
              "duplicate": "cfd3d7",
              "triage:ready": "0e8a16",
              "triage:needs-svg": "d93f0b",
              "triage:needs-license": "fbca04",
              "triage:svg-oversize": "d93f0b",
              "triage:invalid-svg": "b60205",
            };
            for (const name of decision.labels) {
              const color = labelColors[name]
                || (name.startsWith("category:") ? "c5def5" : "ededed");
              try {
                await github.rest.issues.createLabel({ owner, repo, name, color });
              } catch (e) {
                if (e.status !== 422) throw e;
              }
            }

            await github.rest.issues.addLabels({
              owner, repo, issue_number,
              labels: decision.labels,
            });

            // Avoid duplicate comments on edits: look for the marker line
            const marker = "<sub>This comment was generated by the icon-triage workflow.</sub>";
            const existing = await github.paginate(github.rest.issues.listComments, {
              owner, repo, issue_number, per_page: 100,
            });
            const ours = existing.find(c =>
              c.user && c.user.type === "Bot" && c.body && c.body.includes(marker)
            );
            if (ours) {
              await github.rest.issues.updateComment({
                owner, repo, comment_id: ours.id, body: decision.comment,
              });
              core.info(`updated existing triage comment ${ours.id}`);
            } else {
              await github.rest.issues.createComment({
                owner, repo, issue_number, body: decision.comment,
              });
              core.info(`created triage comment on issue #${issue_number}`);
            }

            core.summary
              .addHeading(`Triaged #${issue_number}`)
              .addRaw(`Slug: \`${decision.slug}\` &middot; Duplicate: ${decision.duplicate}`)
              .addList(decision.labels)
              .write();
