/**
 * DedupService: the public surface of the dedup module.
 *
 *   shouldDeliver(eventKey, windowSec) -> true on first occurrence, false
 *                                          while the prior occurrence is
 *                                          still inside its window
 *   purgeExpired()                    -> housekeeping for the worker tick
 *
 * Constructor-injectable so tests can supply an in-memory repository.
 */

import { PrismaDedupRepository, type DedupRepository } from './dedup.repository';
import { DEFAULT_DEDUP_WINDOW_SECONDS } from './types';

export interface DedupServiceOptions {
    repository?: DedupRepository;
    now?: () => Date;
}

export class DedupService {
    private readonly repo: DedupRepository;
    private readonly now: () => Date;

    constructor(opts: DedupServiceOptions = {}) {
        this.repo = opts.repository ?? new PrismaDedupRepository();
        this.now = opts.now ?? (() => new Date());
    }

    static default(): DedupService {
        return new DedupService();
    }

    async shouldDeliver(eventKey: string, windowSeconds: number = DEFAULT_DEDUP_WINDOW_SECONDS): Promise<boolean> {
        return this.repo.claim(eventKey, windowSeconds, this.now());
    }

    async purgeExpired(): Promise<number> {
        return this.repo.purgeExpired(this.now());
    }
}
