interface ErrorResponse {
    message: string;
    status: number;
}
interface HttpOptionsType extends RequestInit {
    headers?: Record<string, any>;
}

interface AssignTagsOptions {
    /**
     * The email address of the subscriber.
     */
    email: string;
    /**
     * If you want to assign tags to a specific list, you can provide the list ID.
     * If you don't provide a list ID, the tags will be assigned to all lists.
     */
    listId?: string;
    /**
     * To assign tags to the subscriber, you can provide the tags.
     *
     * Default: `[]` - Max 10 tags
     */
    tags?: string[];
}
interface AssignTagsRequestOptions extends HttpOptionsType {
}
interface AssignTagsResponseSuccess {
    status: 'ok';
}
interface AssignTagsResponse {
    data: AssignTagsResponseSuccess | null;
    error: ErrorResponse | null;
}

interface DeleteSubscriberByEmailOptions {
    email: string;
    /**
     * If you want to delete from a specific list, you can provide the list ID.
     * If you don't provide a list ID, you will be deleted from all lists.
     */
    listId?: string;
}
interface DeleteSubscriberByEmailRequestOptions extends HttpOptionsType {
}

interface RemoveTagsOptions {
    /**
     * The email address of the subscriber.
     */
    email: string;
    /**
     * If you want to assign tags to a specific list, you can provide the list ID.
     * If you don't provide a list ID, the tags will be assigned to all lists.
     */
    listId?: string;
    /**
     * To assign tags to the subscriber, you can provide the tags.
     *
     * Default: `[]` - Max 10 tags
     */
    tags?: string[];
}
interface RemoveTagsRequestOptions extends HttpOptionsType {
}
interface RemoveTagsResponseSuccess {
    status: 'ok';
}
interface RemoveTagsResponse {
    data: RemoveTagsResponseSuccess | null;
    error: ErrorResponse | null;
}

interface SubscribeOptions {
    listId: string;
    name: string;
    email: string;
    customFields?: Record<string, string>;
    /**
     * It will mark the subscriber as confirmed.
     * and, it'll not send a confirmation email for double opt-in.
     *
     * Default: `false`
     */
    _isConfirmed: boolean;
    /**
     * If you don't want to send a welcome email, you can set this to true.
     *
     * Default: `false`
     */
    _hasWelcomeEmail: boolean;
    /**
     * To assign tags to the subscriber, you can provide the tags.
     *
     * Default: `[]` - Max 10 tags
     */
    _tags?: string[];
}
interface SubscribeRequestOptions extends HttpOptionsType {
}
interface SubscribeResponseSuccess {
    status: 'success' | 'confirm-subscription' | 'already-subscribed';
}
interface SubscribeResponse {
    data: SubscribeResponseSuccess | null;
    error: ErrorResponse | null;
}

interface UnsubscribeOptions {
    email: string;
    /**
     * If you want to unsubscribe from a specific list, you can provide the list ID.
     * If you don't provide a list ID, you will be unsubscribed from all lists.
     */
    listId?: string;
}
interface UnsubscribeRequestOptions extends HttpOptionsType {
}
interface UnsubscribeResponseSuccess {
    status: 'ok';
}
interface UnsubscribeResponse {
    data: UnsubscribeResponseSuccess | null;
    error: ErrorResponse | null;
}

declare class Subscribers {
    private readonly scoop;
    constructor(scoop: Scoop);
    assignTags(payload: AssignTagsOptions, options?: AssignTagsRequestOptions): Promise<AssignTagsResponse>;
    removeTags(payload: RemoveTagsOptions, options?: RemoveTagsRequestOptions): Promise<RemoveTagsResponse>;
    subscribe(payload: SubscribeOptions, options?: SubscribeRequestOptions): Promise<SubscribeResponse>;
    unsubscribe(payload: UnsubscribeOptions, options?: UnsubscribeRequestOptions): Promise<UnsubscribeResponse>;
    deleteByEmail(payload: DeleteSubscriberByEmailOptions, options?: DeleteSubscriberByEmailRequestOptions): Promise<UnsubscribeResponse>;
}

type RequireAtLeastOne<T> = {
    [K in keyof T]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<keyof T, K>>>;
}[keyof T];
interface EmailRenderOptions {
    /**
     * The plain text content of the email.
     */
    text?: string;
    /**
     * The HTML content of the email.
     */
    html?: string;
}
interface EmailOptions extends EmailRenderOptions {
    /**
     * The email address that appears as the sender of the email.
     * Use a friendly name and a valid email address.
     *
     * Example: `John Doe <johndoe@example.com>`
     */
    from: string;
    /**
     * The recipient(s) of the email. Can be a single email address or an array of email addresses.
     */
    to: string | string[];
    /**
     * The email address that should be used for replies. If not provided, replies will go to the 'from' address.
     */
    replyTo?: string;
    /**
     * The subject line of the email.
     */
    subject: string;
    /**
     * The email addresses to carbon copy.
     * The recipients will be visible to other recipients.
     */
    cc?: string[];
    /**
     * The email addresses to blind carbon copy.
     * The recipients will not be visible to other recipients. (i.e. in the `to` or `cc` fields)
     */
    bcc?: string[];
}
type SendEmailOptions = RequireAtLeastOne<EmailRenderOptions> & EmailOptions;
interface SendEmailRequestOptions extends HttpOptionsType {
}
interface SendEmailResponseSuccess {
    status: 'ok';
}
interface SendEmailResponse {
    data: SendEmailResponseSuccess | null;
    error: ErrorResponse | null;
}

declare class Emails {
    private readonly scoop;
    constructor(scoop: Scoop);
    send(payload: SendEmailOptions, options?: SendEmailRequestOptions): Promise<SendEmailResponse>;
}

interface ScoopConfig {
    /**
     * The endpoint to use for API requests.
     * Default: `https://scoop-api.roadmap.sh`
     */
    endpoint?: string;
}
declare class Scoop {
    readonly key: string;
    readonly config: ScoopConfig;
    private headers;
    readonly subscribers: Subscribers;
    readonly emails: Emails;
    constructor(key: string, config?: ScoopConfig);
    fetchRequest<T>(path: string, options?: {}): Promise<{
        data: T | null;
        error: ErrorResponse | null;
    }>;
    post<T>(path: string, entity?: unknown, options?: HttpOptionsType): Promise<{
        data: T | null;
        error: ErrorResponse | null;
    }>;
    get<T>(path: string, options?: HttpOptionsType): Promise<{
        data: T | null;
        error: ErrorResponse | null;
    }>;
    put<T>(path: string, entity: any, options?: HttpOptionsType): Promise<{
        data: T | null;
        error: ErrorResponse | null;
    }>;
    patch<T>(path: string, entity: any, options?: HttpOptionsType): Promise<{
        data: T | null;
        error: ErrorResponse | null;
    }>;
    delete<T>(path: string, query?: unknown): Promise<{
        data: T | null;
        error: ErrorResponse | null;
    }>;
}

export { type ErrorResponse, Scoop, type ScoopConfig };
