/**
 * Analytics Service for email statistics and insights
 */
import { EmailMessage, EmailStats, EmailAnalytics, Contact } from '../types/index.js';
export type ContactSortBy = 'recent' | 'total' | 'sent' | 'received';
export declare class AnalyticsService {
    private inboxEmails;
    private sentEmails;
    private contacts;
    private statsCache;
    private analyticsCache;
    private lastCacheUpdate;
    private cacheValidityMs;
    /**
     * Update the analytics dataset. Pass both inbox and sent folders for accurate
     * volume trends, contact stats, and response-time calculation.
     * Does NOT clear the computed cache — the cache is only cleared when new data
     * differs from what is already stored, preventing spurious invalidation.
     */
    updateEmails(inbox: EmailMessage[], sent?: EmailMessage[]): void;
    /** @deprecated Use updateEmails(inbox, sent) — kept for backward compatibility */
    get emails(): EmailMessage[];
    private invalidateCache;
    private isCacheValid;
    /**
     * Build the contact map from both inbox (received) and sent emails.
     * - inbox emails → the `from` address sent a message to us
     * - sent emails  → the `to` addresses received a message from us
     *
     * Sent recipients are processed FIRST. The MAX_CONTACTS cap drops new
     * contacts in insertion order once full; people the user actually emails are
     * the highest-value contacts, so they must claim their map slots before a
     * flood of one-off inbox senders (newsletters, bounces) can exhaust the cap
     * (PARSE-004, audit-2026-05-28).
     */
    private processContacts;
    private updateContact;
    getEmailStats(): EmailStats;
    getEmailAnalytics(): EmailAnalytics;
    /**
     * Compute response times from sent emails that have an inReplyTo header
     * matching an inbox email. Returns null when there is insufficient data.
     * Times are expressed in hours.
     */
    private calculateResponseTimeStats;
    /**
     * Volume trends split by received (inbox) and sent (sent folder).
     *
     * TIME BASIS: host-local time. Day boundaries (this method) and the hour of
     * day (calculatePeakActivityHours) are both computed against the host's local
     * zone so the two charts derived from the same dataset agree, and so a "Mon"
     * bar reflects the day the user actually experienced rather than UTC. An
     * email received at 9 PM ET Monday now counts toward Monday, not Tuesday-UTC
     * (PARSE-005/006, audit-2026-05-28). No TZ library is used — date keys come
     * from local Date accessors via localDateKey().
     *
     * Buckets are seeded by walking back `days` *calendar* days using local
     * y/m/d construction (not fixed 86.4M-ms steps), so a DST transition can
     * never collapse two local days onto one key or skip a day.
     */
    private calculateVolumeTrends;
    private calculatePeakActivityHours;
    private calculateAttachmentStats;
    getContacts(limit?: number, sortBy?: ContactSortBy): Contact[];
    getVolumeTrends(days?: number): EmailAnalytics['volumeTrends'];
    clearCache(): void;
    clearAll(): void;
    /** Securely wipe all email data from memory. */
    wipeData(): void;
}
//# sourceMappingURL=analytics-service.d.ts.map