// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module.exports = async ({ github, context }) => {
  const owner = context.repo.owner;
  const repo = context.repo.repo;
  const labelName = 'waiting for response';
  const daysUntilClose = 21;

  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));

  // GitHub's pulls REST API does not support filtering by label. In GitHub's
  // data model, pull requests are treated as issues, so we query the issues
  // endpoint with the target label. Since issues are disabled in flutter/packages,
  // this will only return pull requests.
  const prs = await github.paginate(github.rest.issues.listForRepo, {
    owner,
    repo,
    state: 'open',
    labels: labelName,
    per_page: 100,
  });

  for (const pr of prs) {
    if (!pr.pull_request) {
      continue;
    }

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

    const labelEvent = events.reverse().find(
      event =>
        event.event === 'labeled' &&
        event.label?.name === labelName
    );

    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: pr.number,
      since: labeledAt.toISOString(),
      per_page: 100,
    });

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

    // Check for commits after label
    if (!isResponse) {
      const commits = await github.paginate(github.rest.pulls.listCommits, {
        owner,
        repo,
        pull_number: pr.number,
        per_page: 100,
      });

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

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

      continue; // Skip stale check
    }

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

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