import { type Readable } from 'node:stream';
import type { SendMailOptions } from 'nodemailer';
import type { ConfigProvider } from '@adonisjs/core/types';
import { type AsyncOrSync } from '@adonisjs/core/types/common';
import type { SESv2ClientConfig } from '@aws-sdk/client-sesv2';
import type MimeNode from 'nodemailer/lib/mime-node/index.js';
import type { Options as SMTPConnectionOptions } from 'nodemailer/lib/smtp-connection/index.js';
import type { Options as SMTPPoolOptions } from 'nodemailer/lib/smtp-pool/index.js';
import type { Message } from './message.js';
import type { BaseMail } from './base_mail.js';
import type { MailManager } from './mail_manager.js';
import type { MailResponse } from './mail_response.js';
/**
 * Shape of the envelope node after the email has been
 * sent
 */
export type ResponseEnvelope = MimeNode.Envelope;
/**
 * Shape of the recipient
 */
export type Recipient = {
    address: string;
    name: string;
} | string;
/**
 * Available calendar event methods
 */
export type CalendarEventMethod = 'PUBLISH' | 'REQUEST' | 'REPLY' | 'ADD' | 'CANCEL' | 'REFRESH' | 'COUNTER' | 'DECLINECOUNTER';
/**
 * Event options accepted by the icalEvent* methods
 */
export type CalendarEventOptions = {
    method?: CalendarEventMethod;
    filename?: string;
    encoding?: string;
};
/**
 * Shape of data view defined on the message
 */
export type MessageBodyTemplates = {
    html?: {
        template: string;
        data?: any;
    };
    text?: {
        template: string;
        data?: any;
    };
    watch?: {
        template: string;
        data?: any;
    };
};
/**
 * Data shared with the template engine rendering templates
 * to compute email contents.
 */
export type MessageViewHelpers = {
    embedImage: (filePath: string, options?: Omit<AttachmentOptions, 'filename' | 'cid' | 'raw' | 'content'>) => string;
    embedImageData: (data: Buffer | Readable, options?: Omit<AttachmentOptions, 'filename' | 'cid' | 'raw' | 'content'>) => string;
};
/**
 * Attachment options accepted by the attachment
 * methods.
 */
export type AttachmentOptions = Exclude<SendMailOptions['attachments'], undefined>[number];
/**
 * Message node is compatible with nodemailer `sendMail` method
 */
export type NodeMailerMessage = {
    from?: Recipient;
    to?: Recipient[];
    cc?: Recipient[];
    bcc?: Recipient[];
    replyTo?: Recipient[];
    messageId?: SendMailOptions['messageId'];
    subject?: SendMailOptions['subject'];
    inReplyTo?: SendMailOptions['inReplyTo'];
    references?: SendMailOptions['references'];
    encoding?: SendMailOptions['encoding'];
    priority?: SendMailOptions['priority'];
    envelope?: SendMailOptions['envelope'];
    list?: SendMailOptions['list'];
    icalEvent?: CalendarEventOptions & {
        content?: string;
        path?: string;
        href?: string;
    };
    attachments?: SendMailOptions['attachments'];
    headers?: SendMailOptions['headers'];
    html?: SendMailOptions['html'];
    text?: SendMailOptions['text'];
    watch?: SendMailOptions['watchHtml'];
};
/**
 * Shape of the mail transport. Each transport must adhere to
 * this interface
 */
export interface MailTransportContract {
    /**
     * Send email
     */
    send(message: NodeMailerMessage, config?: unknown): Promise<MailResponse<unknown>>;
    /**
     * Cleanup transport long-lived connections
     */
    close?(): void | Promise<void>;
}
/**
 * Factory function to lazily initiate a transport
 */
export type MailManagerTransportFactory = () => MailTransportContract;
/**
 * Shape of the callback passed to the `send` method to compose the
 * message
 */
export type MessageComposeCallback = (message: Message) => void | Promise<void>;
/**
 * Events emitted by the mailer
 */
export type MailEvents = {
    'mail:sending': {
        mailerName: string;
        message: NodeMailerMessage;
        views: MessageBodyTemplates;
    };
    'mail:sent': {
        mailerName: string;
        message: NodeMailerMessage;
        views: MessageBodyTemplates;
        response: MailResponse<unknown>;
    };
    'mail:queueing': {
        mailerName: string;
        message: NodeMailerMessage;
        views: MessageBodyTemplates;
    };
    'mail:queued': {
        metaData?: any;
        mailerName: string;
        message: NodeMailerMessage;
        views: MessageBodyTemplates;
    };
    'queued:mail:error': {
        error: any;
        metaData?: any;
        mailerName: string;
    };
};
/**
 * Mailer contract represents a mailer that can be used to send emails
 */
export interface MailerContract<Transport extends MailTransportContract> {
    name: string;
    /**
     * Reference to the underlying transport
     */
    transport: Transport;
    /**
     * Configure the messenger to use for sending email asynchronously
     */
    setMessenger(messenger: MailerMessenger): this;
    /**
     * Sends a compiled email using the underlying transport
     */
    sendCompiled(mail: {
        message: NodeMailerMessage;
        views: MessageBodyTemplates;
    }, sendConfig?: unknown): Promise<Awaited<ReturnType<Transport['send']>>>;
    /**
     * Queues a compliled email using the messenger
     */
    sendLaterCompiled(mail: {
        message: NodeMailerMessage;
        views: MessageBodyTemplates;
    }, sendConfig?: unknown): Promise<void>;
    /**
     * Sends email
     */
    send(callbackOrMail: MessageComposeCallback | BaseMail, config?: Parameters<Transport['send']>[1]): Promise<Awaited<ReturnType<Transport['send']>>>;
    /**
     * Send an email asynchronously using the mail messenger. The
     * default messenger uses an in-memory queue, unless you have
     * configured a custom messenger.
     */
    sendLater(callbackOrMail: MessageComposeCallback | BaseMail, config?: Parameters<Transport['send']>[1]): Promise<void>;
    /**
     * Invokes `close` method on the transport
     */
    close(): Promise<void>;
}
export type MailerConfig = {
    /**
     * Define a global email address to always use when
     * sending emails
     */
    from?: Recipient;
    /**
     * Define a global replyTo email address to always use
     * when sending emails
     */
    replyTo?: Recipient;
    /**
     * Global data to share with email templates when rendering
     * them using the template engine.
     */
    globals?: Record<string, any>;
};
/**
 * Template engine accepted by the mailer to render
 * templates to compute mail body contents
 */
export interface MailerTemplateEngine {
    /**
     * Render a template to contents
     */
    render(templatePath: string, sharedState?: any, data?: any): AsyncOrSync<string>;
}
/**
 * Messenger accepted by the mailer to send emails asynchronously
 */
export interface MailerMessenger {
    queue(mail: {
        message: NodeMailerMessage;
        views: MessageBodyTemplates;
    }, sendConfig?: unknown): Promise<any>;
}
export type MessageSearchOptions = {
    subject?: string;
    to?: string;
    from?: string;
    attachments?: string[];
};
/**
 * Config accepted by the Mailgun transport at the
 * time of sending the email
 */
export type MailgunRuntimeConfig = {
    oDkim?: boolean;
    oTags?: string[];
    oDeliverytime?: Date;
    oTestMode?: boolean;
    oTracking?: boolean;
    oTrackingClick?: boolean;
    oTrackingOpens?: boolean;
    headers?: {
        [key: string]: string;
    };
    variables?: {
        [key: string]: string;
    };
};
/**
 * Config accepted by the Mailgun transport at the
 * time of constructing the transport
 */
export type MailgunConfig = MailgunRuntimeConfig & {
    baseUrl: string;
    key: string;
    domain: string;
};
/**
 * Response returned by the Mailgun transport
 */
export type MailgunSentMessageInfo = {
    id: string;
    messageId: string;
    envelope: ResponseEnvelope;
};
/**
 * Login options for Oauth2 SMTP login
 */
export type SMTPOauth2 = {
    type: 'OAuth2';
    user: string;
    clientId: string;
    clientSecret: string;
    refreshToken?: string;
    accessToken?: string;
    expires?: string | number;
    accessUrl?: string;
};
/**
 * Login options for simple SMTP login
 */
export type SMTPSimpleAuth = {
    type: 'login';
    user: string;
    pass: string;
};
/**
 * SMTP transport config
 */
export type SMTPConfig = ({
    host: string;
    port?: number | string;
    secure?: boolean;
} | {
    /**
     * Specify the name of a well known service. Overrides the
     * host, port, and secure options
     */
    service?: string;
}) & {
    /**
     * Authentication
     */
    auth?: SMTPSimpleAuth | SMTPOauth2;
} & SMTPConnectionOptions & Partial<Pick<SMTPPoolOptions, 'pool' | 'maxConnections' | 'maxMessages' | 'rateDelta' | 'rateLimit'>>;
/**
 * SES transport config
 */
export type SESConfig = SESv2ClientConfig;
/**
 * Following options can be defined during the `Mail.send` call
 */
export type SparkPostRuntimeConfig = {
    startTime?: Date;
    initialOpen?: boolean;
    openTracking?: boolean;
    clickTracking?: boolean;
    transactional?: boolean;
    sandbox?: boolean;
    skipSuppression?: boolean;
    ipPool?: string;
};
/**
 * Spark post config
 */
export type SparkPostConfig = SparkPostRuntimeConfig & {
    baseUrl: string;
    key: string;
};
/**
 * Response returned by the SparkPost transport
 */
export type SparkPostSentMessageInfo = {
    id: string;
    messageId: string;
    envelope: ResponseEnvelope;
    total_rejected_recipients: number;
    total_accepted_recipients: number;
};
export type ResendRuntimeConfig = {
    tags?: {
        name: string;
        value?: string;
    }[];
};
/**
 * Resend transport config
 */
export type ResendConfig = ResendRuntimeConfig & {
    key: string;
    baseUrl: string;
};
/**
 * Response returned by the Resend API
 */
export type ResendSentMessageInfo = {
    id: string;
    messageId: string;
    envelope: ResponseEnvelope;
};
export type BrevoRuntimeConfig = {
    scheduledAt?: Date;
    tags?: string[];
};
/**
 * Brevo transport config
 */
export type BrevoConfig = BrevoRuntimeConfig & {
    key: string;
    baseUrl: string;
};
/**
 * Response returned by the Brevo API
 */
export type BrevoSentMessageInfo = {
    messageId: string;
    envelope: ResponseEnvelope;
};
export type CloudflareRuntimeConfig = {};
/**
 * Cloudflare transport config
 */
export type CloudflareConfig = CloudflareRuntimeConfig & {
    key: string;
    baseUrl: string;
    accountId: string;
};
/**
 * Response returned by the Cloudflare Email Service API
 */
export type CloudflareSentMessageInfo = {
    messageId: string;
    envelope: ResponseEnvelope;
    success: boolean;
    result?: {
        delivered?: string[];
        permanent_bounces?: string[];
        queued?: string[];
    };
};
export type PostmarkRuntimeConfig = {
    messageStream?: string;
    tag?: string;
    trackOpens?: boolean;
    trackLinks?: 'None' | 'HtmlAndText' | 'HtmlOnly' | 'TextOnly';
    metadata?: Record<string, string>;
};
/**
 * Postmark transport config
 */
export type PostmarkConfig = PostmarkRuntimeConfig & {
    key: string;
    baseUrl: string;
};
/**
 * Response returned by the Postmark API
 */
export type PostmarkSentMessageInfo = {
    messageId: string;
    envelope: ResponseEnvelope;
    MessageID?: string;
    SubmittedAt?: string;
    ErrorCode: number;
    Message: string;
    To?: string;
};
/**
 * A list of known mailers inferred from the user config
 */
export interface MailersList {
}
/**
 * Helper method to resolve configured mailers
 * inside user app
 */
export type InferMailers<T extends ConfigProvider<{
    mailers: Record<string, MailManagerTransportFactory>;
}>> = Awaited<ReturnType<T['resolver']>>['mailers'];
/**
 * Mailer service is a singleton instance of mail
 * manager configured using user app's config
 */
export interface MailService extends MailManager<MailersList extends Record<string, MailManagerTransportFactory> ? MailersList : never> {
}
