import { EmailMessage, Headers, ForwardableEmailMessage } from '@cloudflare/workers-types';
import { MIMEMessage } from 'mimetext/browser';

interface EnhancedMessage extends EmailMessage {
    /**
     * The email message content.
     */
    readonly raw: () => Promise<Uint8Array>;
    /**
     * Size of the email message content.
     */
    readonly size: number;
    /**
     * The email message headers.
     */
    readonly headers: Headers;
    /**
     * Reject this email message by returning a permanent SMTP error back to the connecting client including the given reason.
     * @param reason The reject reason.
     */
    reject?(reason: string): void;
    /**
     * Forward this email message to a verified destination address of the account.
     * @param to Verified destination address.
     * @param headers A [Headers object](https://developer.mozilla.org/en-US/docs/Web/API/Headers).
     * @returns A promise that resolves when the email message is forwarded.
     */
    forward(to: string, headers?: Headers): Promise<void>;
    /**
     * Reply to this email message.
     */
    reply(message: MIMEMessage): Promise<void>;
    /**
     * Whether this email message is sent automatically. (Check the `Auto-Submitted` header)
     * @returns `true` if the email message is sent automatically, `false` otherwise.
     *
     * @see https://tools.ietf.org/html/rfc3834
     */
    isAuto(): boolean;
}
interface Context {
    message: EnhancedMessage;
}
interface Middleware<In extends Context = Context, Out extends Context = In> {
    name: string;
    handle(ctx: In, next: In extends Out ? () => Promise<void> : (ctx: Out) => Promise<void>): Promise<void> | void;
}
type MiddlewareOrHandle<In extends Context = Context, Out extends Context = In> = Middleware<In, Out> | Middleware<In, Out>["handle"];
type MiddlewareOutput<M extends Middleware | Middleware["handle"]> = M extends Middleware<Context, infer Out> ? Out : M extends Middleware<Context, infer Out>["handle"] ? Out : never;

declare class EmailKitCore<Last extends Context> implements Middleware<Last> {
    name: string;
    protected middlewares: Middleware[];
    use<M extends Middleware<Context, any>>(middleware: M extends Middleware<infer In> ? (Last extends In ? M : never) : never): EmailKitCore<Last & MiddlewareOutput<M>>;
    use<F extends Middleware<Context, any>["handle"]>(middleware: F extends Middleware<infer In>["handle"] ? Last extends In ? F : never : never): EmailKitCore<Last & MiddlewareOutput<F>>;
    handle(ctx: Context): Promise<void>;
}
declare class EmailKit<Last extends Context> extends EmailKitCore<Last> {
    use<M extends Middleware<Context, any>>(middleware: M extends Middleware<infer In> ? (Last extends In ? M : never) : never): EmailKit<Last & MiddlewareOutput<M>>;
    use<F extends Middleware<Context, any>["handle"]>(middleware: F extends Middleware<infer In>["handle"] ? Last extends In ? F : never : never): EmailKit<Last & MiddlewareOutput<F>>;
    process(message: ForwardableEmailMessage): Promise<void>;
}

export { type Context, EmailKit, EmailKitCore, type EnhancedMessage, type Middleware, type MiddlewareOrHandle, type MiddlewareOutput };
