import { GitHub } from '@actions/github/lib/utils.js';
import { Context } from '@actions/github/lib/context.js';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import * as glob from '@actions/glob';
import * as io from '@actions/io';
import fetch from 'node-fetch';
import { User } from '@slack/web-api/dist/types/response/UsersLookupByEmailResponse';

type GitHubIssue = {
    id: string;
    title: string;
    number?: number;
    url?: string;
    status?: string;
    labels: Label[];
    type?: string;
    owner?: string;
    repository?: string;
    assignees?: {
        login: string;
    };
    reviewRequests?: {
        login: string;
    };
};
type GitHubComment = {
    id: string;
    author: {
        login: string;
    };
    body: string;
    url?: string;
};
type Label = {
    id: string;
    name: string;
    url: string;
    description?: string;
    color: string;
};
type Labelable = {
    id: string;
    number: number;
    title: string;
    labels: {
        nodes: [
            {
                name: string;
            }
        ];
    };
};
type GitHubMilestone = {
    id: number;
    url: string;
    html_url: string;
    labels_url: string;
    node_id: string;
    number: number;
    state: "open" | "closed";
    title: string;
    description: string | null;
    created_at: string;
    updated_at: string;
    closed_at: string | null;
    due_on: string | null;
    open_issues: number;
    closed_issues: number;
};

type JiraIssue = {
    id: string;
    title: string;
    key: string;
    url?: string;
    status?: string;
    labels: string[];
    type?: string;
};

type QueryResponse = {
    repository: {
        issues?: {
            pageInfo: {
                hasNextPage: boolean;
                endCursor: string;
            };
            nodes: [
                {
                    id: string;
                    number: number;
                    title: string;
                    labels: {
                        nodes: [
                            {
                                name: string;
                            }
                        ];
                    };
                }
            ];
        };
        pullRequests?: {
            pageInfo: {
                hasNextPage: boolean;
                endCursor: string;
            };
            nodes: [
                {
                    id: string;
                    number: number;
                    title: string;
                    labels: {
                        nodes: [
                            {
                                name: string;
                            }
                        ];
                    };
                }
            ];
        };
    };
};

type Toolkit = {
    github: InstanceType<typeof GitHub>;
    context: Context;
    core: typeof core;
    exec: typeof exec;
    glob: typeof glob;
    io: typeof io;
    fetch: typeof fetch;
};

declare function closeIssue(toolkit: Toolkit, issueId: string, reason?: string): Promise<void>;
declare function closePullRequest(toolkit: Toolkit, pullRequestId: string): Promise<void>;
declare function getLabelByName(toolkit: Toolkit, repository: string, labelName: string): Promise<any>;
declare function addLabelToLabelable(toolkit: Toolkit, labelId: string, labelableId: string): Promise<void>;
declare function findIssueWithProjectItems(toolkit: Toolkit, number: number): Promise<{
    node_id: any;
    number: any;
    projectItems: any;
}>;
declare function findPRWithProjectItems(toolkit: Toolkit, number: number): Promise<{
    node_id: any;
    number: any;
    projectItems: any;
}>;
declare function setFieldValue(toolkit: Toolkit, data: {
    projectId: string;
    itemId: string;
    fieldId: string;
    valueId: string;
}): Promise<any>;
declare function getProjectInfo(toolkit: Toolkit, data: {
    number: number;
    organization?: string;
}): Promise<{
    node_id: any;
    title: any;
    fields: any;
}>;
declare function addProjectItem(toolkit: Toolkit, data: {
    projectId: string;
    issueId: string;
}): Promise<{
    node_id: any;
}>;
/**
 * getProjectIdByNumber fetches the project ID for a given project number.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param number - The project number to get the ID for.
 * @param organization - The organization name whose projects to consider.
 */
declare function getProjectIdByNumber(toolkit: Toolkit, number: number, organization?: string | null): Promise<any>;
/**
 * getIssuesByProject fetches all issues from a project.
 *
 * @remarks
 * This function uses pagination to fetch all issues from a project.
 * It will keep fetching until all issues are retrieved.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param projectId - The ID of the project to fetch issues from.
 * @param cursor - The cursor for pagination.
 * @param carry - The issues already fetched.
 */
declare function getIssuesByProject(toolkit: Toolkit, projectId: string, cursor?: string | null, carry?: GitHubIssue[] | null): Promise<GitHubIssue[]>;
/**
 * getCommentsForIssue fetches all comments for a given issue.
 *
 * @remarks
 * This function uses pagination to fetch all comments for an issue.
 * It will keep fetching until all comments are retrieved.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param issueId - The ID of the issue to fetch comments for.
 * @param cursor - The cursor for pagination.
 * @param carry - The comments already fetched.
 */
declare function getCommentsForIssue(toolkit: Toolkit, issueId: string, cursor?: string | null, carry?: GitHubComment[] | null): Promise<any[]>;
/**
 * Gets pull requests matching the given search criteria
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param searchQuery - The GitHub search query to use
 */
declare function getPullRequests(toolkit: Toolkit, searchQuery: string): Promise<any>;
declare function addComment(toolkit: Toolkit, issueId: string, commentBody: string): Promise<GitHubComment>;
/**
 * getVerifiedDomainEmails fetches the verified domain emails for a user account associated with an enterprise.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param login - The login of the user.
 * @param organization - The organization name whose verified domains to consider.
 */
declare function getVerifiedDomainEmails(toolkit: Toolkit, login: string, organization: string): Promise<string[]>;
/**
 * getMilestoneByTitle fetches a milestone by it's title.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param repo - The name of the repository
 * @param milestoneTitle the title of the milestone
 * @param organization - The organization name of the repository
 */
declare function getMilestoneByTitle(toolkit: Toolkit, repo: string, milestoneTitle: string, organization?: string): Promise<GitHubMilestone | undefined>;

declare const jiraHost = "shopware.atlassian.net";
declare const jiraBaseUrl = "https://shopware.atlassian.net/rest/api/3";
/**
 * Makes an API call to JIRA with the provided endpoint and request body.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param endpoint - The JIRA API endpoint to call.
 * @param requestBody - The request body to send with the API call.
 *
 * @return The response from the JIRA API.
 */
declare function callJiraApi(toolkit: Toolkit, endpoint: string, requestBody: object): Promise<any>;

declare class SlackClient {
    private webClient;
    constructor(token: string);
    getUserByEmail(toolkit: Toolkit, email: string): Promise<User | null>;
    sendIMToUser(userId: string, message: string): Promise<void>;
}

declare function cancelStuckWorkflows(toolkit: Toolkit, repo: string, organization?: string): Promise<void>;
declare function checkMissingLiceneInRepos(toolkit: Toolkit, organization?: string): Promise<void>;

/**
 * Branches that must never be deleted by {@link cleanupBranches}. Matches
 * long-lived release branches such as `6.5`, `6.5.0`, `6.6.x` and SaaS release
 * branches like `saas/2025/12`.
 *
 * This is the single source of truth for the exclude pattern used by the
 * branch-cleanup workflow; it is exported so it can be unit-tested and imported
 * by the workflow instead of being duplicated as a YAML string literal.
 */
declare const protectedReleaseBranchRegex: RegExp;
declare function getOldBranches(toolkit: Toolkit, repo: string, excludeRegex?: string | RegExp, organization?: string): Promise<string[] | null>;
declare function cleanupBranches(toolkit: Toolkit, repo: string, organization?: string, excludeRegex?: string | RegExp): Promise<void>;

declare const docIssueReference: string;
/**
 * getDevelopmentIssueForPullRequest fetches the development issue linked to a pull request.
 *
 * @remarks
 * This function searches for pull requests in the Shopware organization that match the given head and assignee.
 * It retrieves the first closing issue reference from the matching pull requests.
 * If a matching development issue is found, it returns the issue details; otherwise, it returns null.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param repo - The repository to search in, formatted as "owner/repo".
 * @param pullRequestNumber - The number of the pull request to search for.
 * @param pullRequestHead - The head branch of the pull request.
 * @param pullRequestAssignee - The assignee of the pull request.
 */
declare function getDevelopmentIssueForPullRequest(toolkit: Toolkit, repo: string, pullRequestNumber: number, pullRequestHead: string, pullRequestAssignee: string): Promise<GitHubIssue | null>;
/**
 * getEpicsInProgressByProject fetches all epics in progress from a project.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param projectId - The ID of the project to fetch issues from.
 */
declare function getEpicsInProgressByProject(toolkit: Toolkit, projectId: string): Promise<GitHubIssue[]>;
/**
 * createDocIssueComment creates a comment on a GitHub issue that references a documentation issue.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param issueId - The ID of the issue to comment on.
 * @param docIssueKey - The key of the documentation issue to reference.
 * @param content - The comment to add.
 */
declare function createDocIssueComment(toolkit: Toolkit, issueId: string, docIssueKey: string, content?: string | null): Promise<GitHubComment>;
/**
 * hasDocIssueComment checks if a GitHub issue has a comment that references a documentation issue.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param issueId - The ID of the issue to check.
 */
declare function hasDocIssueComment(toolkit: Toolkit, issueId: string): Promise<boolean>;
/**
 * referencesDocIssue checks if a comment contains a link to a documentation issue.
 *
 * @param comment - The comment to check.
 */
declare function referencesDocIssue(comment: GitHubComment): boolean;
/**
 * Cleans up needs-triage in issues and pull requests
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param dryRun - If true, only log what would be done without making changes.
 *
 * @remarks
 * This function finds all open issues and pull requests and ensures they have either:
 * - The needs-triage label, or
 * - A label starting with 'domain/' or 'service/'
 * - If an item has a `domain/` or `service/` label, remove the `needs-triage` label
 *
 * Closed items are ignored. The function handles pagination to process all items.
 */
declare function cleanupNeedsTriage(toolkit: Toolkit, dryRun?: boolean): Promise<void>;
declare function findWithProjectItems(toolkit: Toolkit): Promise<{
    node_id: any;
    number: any;
    projectItems: any;
}>;
declare function linkClosingPR(toolkit: Toolkit, issueNumber: number, prReadToken: string, visibilityFilter?: string, org?: string, repo?: string): Promise<void>;

/**
 * createDocumentationTask creates a documentation task in JIRA for a given GitHub issue.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param issue - The issue to create a documentation task for.
 * @param documentationProjectId - The ID of the documentation project.
 * @param description - The description of the documentation task.
 */
declare function createDocumentationTask(toolkit: Toolkit, issue: GitHubIssue, documentationProjectId?: number | null, description?: string | null): Promise<JiraIssue>;

/**
 * setMilestoneForPR sets the milestone for a Pull request or an Issue.
 * If a milestone doesn't exists it will create one.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 */
declare function setMilestoneForPR(toolkit: Toolkit): Promise<void>;
type MoveMilestoneLabelsOptions = {
    /** Current version whose milestone label should be moved, e.g. "6.7.10.0". */
    version: string;
    /** Repository owner. Defaults to "shopware". */
    owner?: string;
    /** Repository name. Defaults to "shopware". */
    repo?: string;
    /**
     * When set, only PRs targeting this base branch are relabelled. PRs
     * targeting a release branch follow a different milestone scheme and must
     * not be bumped, so callers relabelling trunk PRs should pass "trunk".
     * When omitted, PRs targeting any base branch are relabelled.
     */
    baseRefName?: string;
    /** Overrides the DRY_RUN env detection when provided. */
    dryRun?: boolean;
};
/**
 * moveMilestoneLabelsToNextVersion moves the `milestone/<version>` label to the
 * next patch version (`milestone/<version+1>`) on every open PR that still
 * carries it. It is used both when a release is tagged and when a release
 * branch is split off, so the operation is fully parameterized.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param options - see {@link MoveMilestoneLabelsOptions}
 */
declare function moveMilestoneLabelsToNextVersion(toolkit: Toolkit, options: MoveMilestoneLabelsOptions): Promise<void>;
/**
 * updateMilestonesOnRelease updates the milestones on release if a PR didn't
 * get merged in the merge window. It reads the released version from the `TAG`
 * environment variable (e.g. "v6.7.10.0") and delegates to
 * {@link moveMilestoneLabelsToNextVersion} for shopware/shopware.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 */
declare function updateMilestonesOnRelease(toolkit: Toolkit): Promise<1 | undefined>;

/**
 * Sets the status of issues in projects using the provided toolkit.
 *
 * @param toolkit - The toolkit instance to interact with the project management system.
 * @param props - The properties for setting the status.
 * @param props.toStatus - The status to set the issues to.
 * @param props.fromStatus - (Optional) The status to filter issues by before setting the new status. Can be a string which has to match exactly or an instance of RegExp
 *
 * @remarks
 * This function finds issues in projects and updates their status based on the provided `toStatus`.
 * If `fromStatus` is provided, only issues with the matching status will be updated.
 * If the `toStatus` option is not found in the project's status options, the issue will be skipped.
 *
 * @example
 * ```typescript
 * await setStatusInProjects({ github, context, core, exec, glob, io, fetch }, { toStatus: 'In Progress', fromStatus: 'Done' });
 * ```
 */
declare function setStatusInProjects(toolkit: Toolkit, props: {
    toStatus: string;
    fromStatus?: string | RegExp;
}): Promise<void>;
declare function syncPriorities(toolkit: Toolkit, excludeList?: number[]): Promise<void>;
/**
 * createDocumentationTasksForProjects creates documentation tasks for all projects with the given project numbers.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param projectNumbers - The project numbers to create documentation tasks for.
 * @param organization - The organization name whose projects to consider.
 * @param documentationProjectId - The ID of the documentation project.
 * @param description - Prefix for the description of the documentation task.
 * @param comment - Prefix for the documentation task reference comment.
 */
declare function createDocumentationTasksForProjects(toolkit: Toolkit, projectNumbers: number[], organization?: string | null, documentationProjectId?: number | null, description?: string | null, comment?: string | null): Promise<void>;
declare function markStaleIssues(toolkit: Toolkit, projectNumber: number, dryRun: boolean): Promise<void>;
declare function closeStaleIssues(toolkit: Toolkit, dryRun: boolean): Promise<void>;

/**
 * manageOldPullRequests checks for old pull requests and closes them if they have been inactive for a specified number of days.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param organization - The GitHub organization to check for old pull requests.
 * @param days - Consider pull requests old after this many days of inactivity.
 * @param close - If true, the pull request will be closed after sending the reminder.
 */
declare function manageOldPullRequests(toolkit: Toolkit, organization?: string, days?: number, close?: boolean, excludedRepositories?: string[]): Promise<void>;

/**
 * Computed dates for the "branch-off and minor release" announcement, derived
 * from the first Monday of the month following `now`.
 */
type ReleaseSchedule = {
    /** The effective "today" (the override if given, otherwise `now`), as `YYYY-MM-DD`. */
    today: string;
    /** The day the announcement should be sent, as `YYYY-MM-DD`. */
    announcementDate: string;
    /** Human-readable on-prem release date, e.g. `Monday, July 7, 2025`. */
    onpremReleaseDate: string;
    /** Human-readable branch-off date, e.g. `Monday, June 23, 2025`. */
    branchoffDate: string;
    /** Whether `today` is the announcement day. */
    notify: boolean;
};
/**
 * Computes the release-announcement schedule.
 *
 * The on-prem release happens on the first Monday of the month after `now`.
 * Branch-off is 14 days before that, and the announcement 5 days before
 * branch-off. All calculations are performed in UTC to match the GitHub Actions
 * runner behaviour of the previous shell implementation.
 *
 * @param now - The current date. Only its year/month drive the schedule.
 * @param overrideToday - Optional `YYYY-MM-DD` string used in place of `now`
 *   for the `notify` comparison (used for manual testing of the workflow).
 */
declare function computeReleaseSchedule(now: Date, overrideToday?: string | null): ReleaseSchedule;

/**
 * Sends a message to a Slack user identified by their email address.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param emails - The email address(es) of the Slack user to send the message to.
 * @param message - The message to send.
 */
declare function sendSlackMessageForEMail(toolkit: Toolkit, emails: string[], message: string): Promise<void>;
/**
 * Gets a Slack user by their email address.
 *
 * @param toolkit - Octokit instance. See: https://octokit.github.io/rest.js
 * @param emails - The email address(es) of the Slack user.
 * @param message - The message to send.
 */
declare function getSlackUserByEmail(toolkit: Toolkit, emails: string[]): Promise<User | null>;

export { SlackClient, addComment, addLabelToLabelable, addProjectItem, callJiraApi, cancelStuckWorkflows, checkMissingLiceneInRepos, cleanupBranches, cleanupNeedsTriage, closeIssue, closePullRequest, closeStaleIssues, computeReleaseSchedule, createDocIssueComment, createDocumentationTask, createDocumentationTasksForProjects, docIssueReference, findIssueWithProjectItems, findPRWithProjectItems, findWithProjectItems, getCommentsForIssue, getDevelopmentIssueForPullRequest, getEpicsInProgressByProject, getIssuesByProject, getLabelByName, getMilestoneByTitle, getOldBranches, getProjectIdByNumber, getProjectInfo, getPullRequests, getSlackUserByEmail, getVerifiedDomainEmails, hasDocIssueComment, jiraBaseUrl, jiraHost, linkClosingPR, manageOldPullRequests, markStaleIssues, moveMilestoneLabelsToNextVersion, protectedReleaseBranchRegex, referencesDocIssue, sendSlackMessageForEMail, setFieldValue, setMilestoneForPR, setStatusInProjects, syncPriorities, updateMilestonesOnRelease };
export type { GitHubComment, GitHubIssue, GitHubMilestone, JiraIssue, Label, Labelable, MoveMilestoneLabelsOptions, QueryResponse, ReleaseSchedule, Toolkit };
