/**
 * SQLite Contributor Repository (spec 097, FR-21).
 *
 * Backed by the `contributors` table (migration 101). All queries use
 * parameterized statements; the leaderboard query uses the indexed
 * `pr_count` and `last_contribution_at` columns.
 */
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 { inject, injectable } from 'tsyringe';
import { toDatabase, fromDatabase, } from '../persistence/sqlite/mappers/contributor.mapper.js';
/**
 * Returns the [start, endExclusive) UTC ms boundaries of the calendar month
 * containing `now`.
 */
function currentMonthBoundsUtc(now) {
    const year = now.getUTCFullYear();
    const month = now.getUTCMonth();
    const start = Date.UTC(year, month, 1);
    const endExclusive = Date.UTC(year, month + 1, 1);
    return { start, endExclusive };
}
let SQLiteContributorRepository = class SQLiteContributorRepository {
    db;
    constructor(db) {
        this.db = db;
    }
    async create(contributor) {
        const row = toDatabase(contributor);
        this.db
            .prepare(`INSERT INTO contributors
           (id, github_login, display_name, avatar_url, lane, level,
            first_contribution_at, last_contribution_at, pr_count, issue_count,
            created_at, updated_at)
         VALUES (@id, @github_login, @display_name, @avatar_url, @lane, @level,
                 @first_contribution_at, @last_contribution_at, @pr_count, @issue_count,
                 @created_at, @updated_at)`)
            .run(row);
    }
    async findById(id) {
        const row = this.db.prepare('SELECT * FROM contributors WHERE id = ? LIMIT 1').get(id);
        return row ? fromDatabase(row) : null;
    }
    async findByGitHubLogin(login) {
        const row = this.db
            .prepare('SELECT * FROM contributors WHERE github_login = ? LIMIT 1')
            .get(login);
        return row ? fromDatabase(row) : null;
    }
    async update(contributor) {
        const row = toDatabase(contributor);
        this.db
            .prepare(`UPDATE contributors
            SET github_login          = @github_login,
                display_name          = @display_name,
                avatar_url            = @avatar_url,
                lane                  = @lane,
                level                 = @level,
                first_contribution_at = @first_contribution_at,
                last_contribution_at  = @last_contribution_at,
                pr_count              = @pr_count,
                issue_count           = @issue_count,
                updated_at            = @updated_at
          WHERE id = @id`)
            .run(row);
    }
    async delete(id) {
        this.db.prepare('DELETE FROM contributors WHERE id = ?').run(id);
    }
    async listAll() {
        const rows = this.db
            .prepare('SELECT * FROM contributors ORDER BY github_login ASC')
            .all();
        return rows.map(fromDatabase);
    }
    async findTopByPrCount(options) {
        if (options.limit <= 0)
            return [];
        if (options.scope === 'allTime') {
            const rows = this.db
                .prepare(`SELECT * FROM contributors
             ORDER BY pr_count DESC, github_login ASC
             LIMIT ?`)
                .all(options.limit);
            return rows.map(fromDatabase);
        }
        const { start, endExclusive } = currentMonthBoundsUtc(new Date());
        const rows = this.db
            .prepare(`SELECT * FROM contributors
           WHERE last_contribution_at >= ? AND last_contribution_at < ?
           ORDER BY pr_count DESC, github_login ASC
           LIMIT ?`)
            .all(start, endExclusive, options.limit);
        return rows.map(fromDatabase);
    }
};
SQLiteContributorRepository = __decorate([
    injectable(),
    __param(0, inject('Database')),
    __metadata("design:paramtypes", [Object])
], SQLiteContributorRepository);
export { SQLiteContributorRepository };
