import { EventEmitter } from 'events';

/**
 * Configuration for the mail transporter.
 * @typedef {Object} MailConfig
 * @property {string} host - The SMTP host (e.g., smtp.gmail.com).
 * @property {number} port - The SMTP port (e.g., 587).
 * @property {string} user - The SMTP username (e.g., your-email@gmail.com).
 * @property {string} pass - The SMTP password or app-specific password.
 * @property {boolean} [secure] - Whether to use a secure connection (defaults to true if port is 465).
 */
interface MailConfig {
    host: string;
    port: number;
    user: string;
    pass: string;
    secure?: boolean;
}
/**
 * Options for configuring the WaitlistMailer.
 * @typedef {Object} WaitlistMailerOptions
 * @property {string} [companyName] - The name of the company for email templates.
 * @property {string} [mongoUri] - The MongoDB connection URI (e.g., mongodb://localhost:27017/waitlistdb).
 * @property {Object} [sqlConfig] - Configuration for SQL databases.
 * @property {'postgres' | 'mysql'} sqlConfig.dialect - The SQL dialect (PostgreSQL or MySQL).
 * @property {string} sqlConfig.host - The SQL database host.
 * @property {number} sqlConfig.port - The SQL database port.
 * @property {string} sqlConfig.username - The SQL database username.
 * @property {string} sqlConfig.password - The SQL database password.
 * @property {string} sqlConfig.database - The SQL database name.
 */
interface WaitlistMailerOptions {
    companyName?: string;
    mongoUri?: string;
    sqlConfig?: {
        dialect: 'postgres' | 'mysql' | 'sqlite';
        host: string;
        port: number;
        username: string;
        password: string;
        database: string;
    };
}
/**
 * Enum for storage types.
 * @enum {string}
 */
declare enum StorageType {
    Local = "local",
    Db = "db",
    Sql = "sql"
}
/**
 * Main class for managing waitlists and sending confirmation emails.
 * @class WaitlistMailer
 * @extends {EventEmitter}
 */
declare class WaitlistMailer extends EventEmitter {
    private storage;
    private waitlist;
    private transporter;
    private fromEmail;
    private companyName;
    private mongoUri?;
    private sqlConnection?;
    private initialized;
    /**
     * Creates an instance of WaitlistMailer.
     * @param {StorageType} [storage=StorageType.Local] - The storage type (local, db, or sql).
     * @param {MailConfig} mailConfig - The mail configuration.
     * @param {WaitlistMailerOptions} [options] - Additional options for the mailer.
     * @throws {Error} If mailConfig parameters are invalid.
     */
    constructor(storage: StorageType | undefined, mailConfig: MailConfig, options?: WaitlistMailerOptions);
    /**
     * Initializes the mailer, including database connections and data loading.
     * @private
     * @returns {Promise<void>}
     */
    private initialize;
    /**
     * Verifies the Nodemailer transporter configuration.
     * @private
     * @returns {Promise<void>}
     * @throws {Error} If transporter verification fails.
     */
    private verifyTransporter;
    /**
     * Initializes the database storage (MongoDB or SQL).
     * @private
     * @returns {Promise<void>}
     */
    private initializeStorage;
    /**
     * Initializes the Sequelize model and connection.
     * @private
     * @returns {Promise<void>}
     */
    private initializeSequelize;
    /**
     * Loads initial data from the database into memory.
     * @private
     * @returns {Promise<void>}
     */
    private loadInitialData;
    /**
     * Loads data from MongoDB.
     * @private
     * @returns {Promise<void>}
     */
    private loadFromMongo;
    /**
     * Loads data from SQL.
     * @private
     * @returns {Promise<void>}
     */
    private loadFromSql;
    /**
     * Validates an email address using validator.js.
     * @private
     * @param {string} email - The email to validate.
     * @returns {{ isValid: boolean; message?: string }} - The validation result.
     */
    private validateEmail;
    /**
     * Handles errors and emits error events.
     * @private
     * @param {string} context - The context where the error occurred.
     * @param {string} message - A descriptive error message.
     * @param {unknown} error - The error object.
     */
    private handleError;
    /**
     * Persists an email to the database.
     * @private
     * @param {string} email - The email to persist.
     * @returns {Promise<void>}
     */
    private persistEmail;
    /**
     * Removes an email from the database.
     * @private
     * @param {string} email - The email to remove.
     * @returns {Promise<void>}
     */
    private removePersistedEmail;
    /**
     * Checks if the mailer is initialized.
     * @returns {boolean} - True if initialized, false otherwise.
     */
    isInitialized(): boolean;
    /**
     * Waits for the mailer to initialize.
     * @returns {Promise<void>}
     */
    waitForInitialization(): Promise<void>;
    /**
     * Adds an email to the waitlist.
     * @param {string} email - The email to add.
     * @returns {Promise<boolean>} - True if the email was added successfully, false otherwise.
     * @throws {Error} If persistence fails.
     */
    addEmail(email: string): Promise<boolean>;
    /**
     * Removes an email from the waitlist.
     * @param {string} email - The email to remove.
     * @returns {Promise<boolean>} - True if the email was removed successfully, false otherwise.
     * @throws {Error} If removal fails.
     */
    removeEmail(email: string): Promise<boolean>;
    /**
     * Gets the current waitlist.
     * @returns {string[]} - An array of emails in the waitlist.
     */
    getWaitlist(): string[];
    /**
     * Clears the waitlist.
     * @returns {Promise<void>}
     */
    clearWaitlist(): Promise<void>;
    /**
     * Sends a confirmation email.
     * @param {string} email - The email to send to.
     * @param {(email: string) => string} subjectTemplate - A function to generate the email subject.
     * @param {(email: string) => string} bodyTemplate - A function to generate the email body.
     * @returns {Promise<boolean>} - True if the email was sent successfully, false otherwise.
     */
    sendConfirmation(email: string, subjectTemplate: (email: string) => string, bodyTemplate: (email: string) => string): Promise<boolean>;
    /**
     * Sends a confirmation email using a template file.
     * @param {string} email - The email to send to.
     * @param {(email: string) => string} subjectTemplate - A function to generate the email subject.
     * @param {string} templatePath - The path to the template file.
     * @param {Record<string, string>} [replacements={}] - Replacements for the template.
     * @returns {Promise<boolean>} - True if the email was sent successfully, false otherwise.
     */
    sendConfirmationFromFile(email: string, subjectTemplate: (email: string) => string, templatePath: string, replacements?: Record<string, string>): Promise<boolean>;
    /**
     * Sends a confirmation email with retry logic.
     * @param {string} email - The email to send to.
     * @param {(email: string) => string} subjectTemplate - A function to generate the email subject.
     * @param {(email: string) => string} bodyTemplate - A function to generate the email body.
     * @param {number} [maxRetries=3] - The maximum number of retry attempts.
     * @param {number} [retryDelay=1000] - The delay between retries in milliseconds.
     * @returns {Promise<boolean>} - True if the email was sent successfully, false otherwise.
     */
    sendConfirmationWithRetry(email: string, subjectTemplate: (email: string) => string, bodyTemplate: (email: string) => string, maxRetries?: number, retryDelay?: number): Promise<boolean>;
    /**
     * Sends confirmation emails to all emails in the waitlist.
     * @param {(email: string) => string} subjectTemplate - A function to generate the email subject.
     * @param {(email: string) => string} bodyTemplate - A function to generate the email body.
     * @param {number} [maxRetries=3] - The maximum number of retry attempts per email.
     * @param {number} [retryDelay=1000] - The delay between retries in milliseconds.
     * @returns {Promise<number>} - The number of successfully sent emails.
     */
    sendBulkConfirmation(subjectTemplate: (email: string) => string, bodyTemplate: (email: string) => string, maxRetries?: number, retryDelay?: number): Promise<number>;
    /**
     * Finds emails in the waitlist that match a pattern.
     * @param {string} pattern - The pattern to search for.
     * @returns {Promise<string[]>} - An array of matching emails.
     */
    findEmailsByPattern(pattern: string): Promise<string[]>;
    /**
     * Counts the number of emails in the waitlist within a date range.
     * @param {Date} [start] - The start date of the range.
     * @param {Date} [end] - The end date of the range.
     * @returns {Promise<number>} - The count of emails.
     */
    countWaitlistByDate(start?: Date, end?: Date): Promise<number>;
    /**
     * Saves the waitlist to the database.
     * @returns {Promise<boolean>} - True if the waitlist was saved successfully, false otherwise.
     */
    saveWaitlist(): Promise<boolean>;
    /**
     * Closes all database connections.
     * @returns {Promise<void>}
     */
    close(): Promise<void>;
}

export { StorageType, WaitlistMailer };
