module.exports = async ({ github, context }) => {
  const owner = context.repo.owner;
  const repo = context.repo.repo;
  const labelName = 'waiting for response';
  // TODO(chunhtai): Remove this once all issues have applied or reapplied the
  // label. This should happen after 21 days.
  const oldLabelName = 'waiting for customer response';
  const daysUntilClose = 21;
  const issueCloseComment = `Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now.

If you find this problem please file a new issue with the same description, what happens, logs and the output of 'flutter doctor -v'. All system setups can be slightly different so it's always better to open new issues and reference the related ones.

Thanks for your contribution.`;

  const prCloseComment = `This pull request is being closed because it has not been updated in the last 21 days after a request for more information.

If you are still working on this, please feel free to reopen it or file a new pull request.

Thanks for your contribution.`;

  const now = new Date();
  const closeDate = new Date(now.getTime() - (daysUntilClose * 24 * 60 * 60 * 1000));

  // Fetch issues and PRs with label
  const issues = await github.paginate(github.rest.issues.listForRepo, {
    owner,
    repo,
    state: 'open',
    labels: labelName,
  });

  for (const issue of issues) {
    const isPr = issue.pull_request !== undefined;

    // Fetch timeline events to find label date
    const events = await github.paginate(github.rest.issues.listEvents, {
      owner,
      repo,
      issue_number: issue.number,
    });

    const labelEvent = events.reverse().find(
      event =>
        event.event === 'labeled' &&
        // Issues that applied the label before the renaming still use oldLabelName.
        (event.label.name === labelName || event.label.name === oldLabelName)
    );

    if (!labelEvent) {
      continue; // Skip if label not found in events
    }

    const labeledAt = new Date(labelEvent.created_at);
    let isResponse = false;

    // Check for author comments after label
    const comments = await github.paginate(github.rest.issues.listComments, {
      owner,
      repo,
      issue_number: issue.number,
      since: labeledAt.toISOString(),
    });

    for (const comment of comments) {
      if (comment.user.id === issue.user.id && new Date(comment.created_at) > labeledAt) {
        isResponse = true;
        break;
      }
    }

    // Check for commits after label if it's a PR
    if (!isResponse && isPr) {
      const commits = await github.paginate(github.rest.pulls.listCommits, {
        owner,
        repo,
        pull_number: issue.number,
      });

      for (const commit of commits) {
        const commitDate = new Date(commit.commit.committer.date);
        if (commitDate > labeledAt) {
          isResponse = true;
          break;
        }
      }
    }

    if (isResponse) {
      console.log(`Removing label from #${issue.number} as author responded.`);
      await github.rest.issues.removeLabel({
        owner,
        repo,
        issue_number: issue.number,
        name: labelName,
      });

      continue; // Skip stale check
    }

    // Stale check
    if (issue.state === 'open') {
      if (labeledAt < closeDate) {
        if (issue.locked) {
          console.log(`Skipping #${issue.number} because the conversation is locked.`);
          continue;
        }

        console.log(`Closing #${issue.number} due to no response.`);
        const body = isPr ? prCloseComment : issueCloseComment;
        if (body) {
          await github.rest.issues.createComment({
            owner,
            repo,
            issue_number: issue.number,
            body: body,
          });
        }
        await github.rest.issues.update({
          owner,
          repo,
          issue_number: issue.number,
          state: 'closed',
        });
      }
    }
  }
};
