/**
 * WelcomeFirstTimeContributorUseCase — spec 097, FR-28.
 *
 * Triggered on `pull_request.opened`. If the PR opener has zero prior
 * merged PRs in the target repository:
 *   1. Upsert a `Contributor` row (idempotent on github_login).
 *   2. Emit a `RecognitionEvent` of kind `firstPR` (idempotent on
 *      (contributor_id, kind, pr_number) — see NFR-11 / FR-22).
 *   3. Generate a welcome comment.
 *   4. Gate the comment via `IContributorActionGate` and post via
 *      `IGitHubIssueWriter` only when approved (NFR-5).
 *   5. Fire a desktop notification so a maintainer notices the PR.
 *
 * Non-first-timers are a no-op — the use case returns early without
 * writing or notifying.
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { randomUUID } from 'node:crypto';
import { inject, injectable } from 'tsyringe';
import { ContributorLevel, RecognitionKind, } from '../../../domain/generated/output.js';
let WelcomeFirstTimeContributorUseCase = class WelcomeFirstTimeContributorUseCase {
    fetcher;
    contributors;
    events;
    issueWriter;
    gate;
    notifier;
    constructor(fetcher, contributors, events, issueWriter, gate, notifier) {
        this.fetcher = fetcher;
        this.contributors = contributors;
        this.events = events;
        this.issueWriter = issueWriter;
        this.gate = gate;
        this.notifier = notifier;
    }
    async execute(input) {
        const mergedCount = await this.fetcher.getMergedPrCount(input.prRef.owner, input.prRef.repo, input.authorLogin);
        if (mergedCount > 0)
            return { firstTime: false };
        const contributor = await this.upsertContributor(input);
        const recognitionEvent = await this.recordFirstPr(contributor.id, input.prRef.issueNumber);
        const commentBody = renderWelcomeComment(input.authorLogin);
        const gateDecision = await this.gate.gate({
            kind: 'github-comment',
            summary: `Welcome comment for first-time contributor @${input.authorLogin} on PR #${input.prRef.issueNumber}`,
            context: { login: input.authorLogin, prNumber: input.prRef.issueNumber },
        });
        let commentPosted = false;
        if (gateDecision.approved) {
            await this.issueWriter.addComment(input.prRef, commentBody);
            commentPosted = true;
        }
        this.notifier.send('New first-time contributor 🎉', `@${input.authorLogin} opened PR #${input.prRef.issueNumber} in ${input.prRef.owner}/${input.prRef.repo}.`);
        return {
            firstTime: true,
            contributor,
            recognitionEvent,
            commentPosted,
            gateRationale: gateDecision.rationale,
        };
    }
    async upsertContributor(input) {
        const existing = await this.contributors.findByGitHubLogin(input.authorLogin);
        const nowIso = new Date().toISOString();
        if (existing)
            return existing;
        const fresh = {
            id: randomUUID(),
            createdAt: nowIso,
            updatedAt: nowIso,
            githubLogin: input.authorLogin,
            displayName: input.authorDisplayName,
            avatarUrl: input.authorAvatarUrl,
            level: ContributorLevel.User,
            firstContributionAt: nowIso,
            lastContributionAt: nowIso,
            prCount: 0,
            issueCount: 0,
        };
        await this.contributors.create(fresh);
        return fresh;
    }
    async recordFirstPr(contributorId, prNumber) {
        const nowIso = new Date().toISOString();
        const event = {
            id: randomUUID(),
            createdAt: nowIso,
            updatedAt: nowIso,
            contributorId,
            kind: RecognitionKind.FirstPR,
            occurredAt: nowIso,
            prNumber,
        };
        await this.events.insert(event);
        return event;
    }
};
WelcomeFirstTimeContributorUseCase = __decorate([
    injectable(),
    __param(0, inject('IExternalIssueFetcher')),
    __param(1, inject('IContributorRepository')),
    __param(2, inject('IRecognitionEventRepository')),
    __param(3, inject('IGitHubIssueWriter')),
    __param(4, inject('IContributorActionGate')),
    __param(5, inject('IDesktopNotifier')),
    __metadata("design:paramtypes", [Object, Object, Object, Object, Object, Object])
], WelcomeFirstTimeContributorUseCase);
export { WelcomeFirstTimeContributorUseCase };
function renderWelcomeComment(login) {
    return [
        `Welcome to the project, @${login} 🎉`,
        '',
        'Thanks for opening your first PR here. A few things to know:',
        '- A maintainer will review shortly — feel free to ping if it has been quiet.',
        '- Conventional Commits are enforced (e.g. `feat(scope): subject`).',
        '- `pnpm validate` runs lint + typecheck + tests locally if you want to pre-flight CI.',
        '',
        "We're glad you're here.",
    ].join('\n');
}
