# Closes issues that are inactive, likely non-issues, or awaiting a response that never came.
# Runs daily. Skips issues with active discussion (3+ non-bot comments), reopened issues,
# milestones, or assignees.
name: 🎯 Close Stale Issues

on:
  workflow_dispatch:
  schedule:
    - cron: '0 1 * * *'

permissions:
  issues: write
  pull-requests: write

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:

      - name: Exempt actively discussed or reopened issues 💬
        uses: actions/github-script@v8
        with:
          github-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
          script: |
            const { owner, repo } = context.repo;
            const KEEP_OPEN = '📌 Keep Open';
            const BOT = 'liss-bot';
            const MIN = 3;

            const exempt = (number, reason) => github.rest.issues
              .addLabels({ owner, repo, issue_number: number, labels: [KEEP_OPEN] })
              .then(() => core.info(`Exempted #${number} (${reason})`));

            const hasEnoughHumanComments = async (issue) => {
              if (issue.comments < MIN) return false;
              const comments = await github.paginate(github.rest.issues.listComments, {
                owner, repo, issue_number: issue.number, per_page: 100,
              });
              return comments.filter(c => c.user?.login !== BOT).length >= MIN;
            };

            const wasReopened = async (number) => {
              const { data } = await github.rest.issues.listEvents({
                owner, repo, issue_number: number, per_page: 100,
              });
              return data.some(e => e.event === 'reopened');
            };

            const issues = await github.paginate(github.rest.issues.listForRepo, {
              owner, repo, state: 'open', per_page: 100,
            });

            for (const issue of issues) {
              if (issue.pull_request) continue;
              if (issue.labels.some(l => l.name === KEEP_OPEN)) continue;
              try {
                if (await hasEnoughHumanComments(issue)) {
                  await exempt(issue.number, '3+ non-bot comments');
                } else if (await wasReopened(issue.number)) {
                  await exempt(issue.number, 'previously reopened');
                }
              } catch (e) {
                core.warning(`Failed to process #${issue.number}: ${e.message}`);
              }
            }

      - name: Close stale issues ⚰️
        uses: actions/stale@v10
        with:
          repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
          days-before-stale: 120
          days-before-close: 7
          days-before-pr-stale: -1
          operations-per-run: 30
          remove-stale-when-updated: true
          enable-statistics: true
          exempt-issue-labels: '📌 Keep Open,✅ Fixed'
          exempt-all-milestones: true
          close-issue-reason: not_planned
          stale-issue-message: >
            This issue has gone 4 months without an update. To keep the ticket
            open, please indicate that it is still relevant in a comment below.
            Otherwise it will be closed in 7 days.
          close-issue-message: >
            This issue was automatically closed because it has been inactive
            for over 4 months with no activity.
          stale-issue-label: '⚰️ Stale'
          close-issue-label: '🕸️ Inactive'
          labels-to-add-when-unstale: '📌 Keep Open'

      - name: Close issues without response 🚏
        uses: actions/stale@v10
        with:
          repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
          days-before-stale: 7
          days-before-close: 3
          days-before-pr-stale: -1
          operations-per-run: 30
          remove-stale-when-updated: true
          exempt-issue-labels: '📌 Keep Open,✅ Fixed'
          exempt-all-milestones: true
          only-labels: '🚏 Awaiting User Response'
          stale-issue-message: >
            Hello! Looks like additional info is required for this issue to be
            addressed. Don't forget to provide this within the next few days to
            keep your ticket open.
          close-issue-message: 'Issue closed due to no response from user.'
          stale-issue-label: '🛑 No Response'
          close-issue-label: '🕸️ Inactive'
          labels-to-remove-when-unstale: '🚏 Awaiting User Response,🛑 No Response'

      - name: Notify repo owner to respond 👤
        uses: actions/stale@v10
        with:
          repo-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
          days-before-stale: 7
          days-before-close: 365
          operations-per-run: 30
          remove-stale-when-updated: true
          exempt-all-milestones: true
          exempt-issue-labels: '📌 Keep Open'
          exempt-pr-labels: '📌 Keep Open'
          only-labels: '👤 Awaiting Maintainer Response'
          stale-issue-message: Hey @Lissy93 - Don't forget to respond!
          stale-pr-message: Hey @Lissy93 - Don't forget to respond!
          close-issue-message: 'Closed due to no response from repo author for over a year'
          close-pr-message: 'Closed due to no response from repo author for over a year'
          stale-issue-label: '👤 Awaiting Maintainer Response'
          stale-pr-label: '👤 Awaiting Maintainer Response'
          close-issue-label: '🕸️ Inactive'
          close-pr-label: '🕸️ Inactive'
          labels-to-remove-when-unstale: '👤 Awaiting Maintainer Response'
