/**
 * Scheduler Service — queues emails for future delivery.
 *
 * Scheduled emails are persisted to a JSON file so they survive process
 * restarts. A background interval (60 s) checks for due emails and sends
 * them via the SMTPService. Overdue emails from a previous run are processed
 * immediately on startup.
 */
import { ScheduledEmail, SendEmailOptions } from "../types/index.js";
import { SMTPService } from "./smtp-service.js";
/**
 * Result of cancelling a scheduled email.
 *
 * `{ ok: false, error: "in_flight" }` is the SMTP-002 signal: the send is
 * already past the await-point in processDue. Callers must NOT treat this as
 * a successful cancel — the message may already be on the wire.
 */
export type CancelResult = {
    ok: true;
} | {
    ok: false;
    error: "not_found" | "already_final" | "in_flight";
};
export declare class SchedulerService {
    private readonly smtpService;
    private readonly storePath;
    private items;
    private timer;
    private isProcessing;
    constructor(smtpService: SMTPService, storePath: string);
    start(): void;
    stop(): void;
    /**
     * Queue an email for delivery at `sendAt`.
     *
     * @throws If `sendAt` is not in the valid window [now+60s, now+30d].
     * @returns The assigned scheduled email ID.
     */
    schedule(options: SendEmailOptions, sendAt: Date): string;
    /**
     * Cancel a scheduled email.
     *
     * - `"pending"`: marked cancelled, persisted, returns `{ ok: true }`.
     * - `"sending"`: the cooperative-stop signal — status is flipped to
     *   `"cancelled"` so processDue's post-await guard will skip the
     *   status-to-sent flip, but the SMTP send is already on the wire and may
     *   succeed. Returns `{ ok: false, error: "in_flight" }` so the caller can
     *   warn the user that the message may still be delivered.
     * - `"sent" | "failed" | "cancelled"`: terminal state, no-op, returns
     *   `{ ok: false, error: "already_final" }`.
     * - unknown id: `{ ok: false, error: "not_found" }`.
     */
    cancel(id: string): CancelResult;
    /** Return all scheduled emails sorted by scheduledAt ascending. */
    list(): ScheduledEmail[];
    /** Return only pending items. */
    pending(): ScheduledEmail[];
    processDue(): Promise<void>;
    private load;
    /**
     * Remove old non-pending records to prevent unbounded array growth.
     *
     * Strategy:
     *   1. Keep all pending items (they must not be dropped).
     *   2. For non-pending (sent/failed/cancelled), keep only those created
     *      within MAX_HISTORY_AGE_MS.
     *   3. If the remaining non-pending count still exceeds MAX_HISTORY_RECORDS,
     *      keep only the most-recently-created MAX_HISTORY_RECORDS entries.
     */
    private pruneHistory;
    private persist;
}
//# sourceMappingURL=scheduler.d.ts.map