declare type CompletedEvent = {
    porting: Porting;
};

declare type CustomizableEmbedProps = EmbedOptions;

declare const defaultText: {
    'field.accountNumber.label': string;
    'field.accountNumber.error.required': string;
    'field.accountPin.label': string;
    'field.accountPin.error.required': string;
    'field.accountPin.error.cleared': string;
    'field.firstName.label': string;
    'field.firstName.error.required': string;
    'field.lastName.label': string;
    'field.lastName.error.required': string;
    'field.birthday.label': string;
    'field.birthday.error.required': string;
    'field.line1.label': string;
    'field.line1.error.required': string;
    'field.line2.label': string;
    'field.city.label': string;
    'field.city.error.required': string;
    'field.postalCode.label': string;
    'field.postalCode.error.required': string;
    'field.state.label': string;
    'field.state.error.format': string;
    'field.country.label': string;
    'field.country.error.required': string;
    'field.country.error.format': string;
    'field.donorProviderApproval.label': string;
    'field.donorProviderApproval.error.required': string;
};

declare type EmbedOptions = {
    formId?: string;
    className?: {
        form?: (state: FormState) => string;
        field?: (state: FieldState) => string;
        input?: (state: FieldState) => string;
        label?: (state: FieldState) => string;
        error?: (state: Omit<FieldState, 'valid'>) => string;
    };
    text?: Partial<typeof defaultText>;
};

export declare type Events = {
    validationChange: ValidationChangeEvent;
    submitStatus: SubmitStatusEvent;
    completed: CompletedEvent;
    stepChange: StepChangeEvent;
};

declare type FieldState = {
    name: string;
    dirty: boolean;
    touched: boolean;
    valid: boolean;
};

declare type FormState = {
    name: string;
    dirty: boolean;
    valid: boolean;
    submitting: boolean;
    touched: boolean;
};

declare type Handler<T = unknown> = (event: T) => void;

declare type Porting = {
    object: 'porting';
    id: string;
    accountNumber: string | null;
    accountPinExists: boolean;
    address: PortingAddress | null;
    birthday: string | null;
    declinedAttempts: number;
    declinedCode: string | null;
    declinedMessage: string | null;
    donorProvider: ServiceProvider | null;
    donorProviderApproval: boolean | null;
    firstName: string | null;
    lastName: string | null;
    phoneNumber: string;
    provider: string;
    recipientProvider: ServiceProvider;
    required: PortingRequiredField[];
    status: PortingStatus;
    subscription: string | null;
    user: string;
    canceledAt: string | null;
    completedAt: string | null;
    createdAt: string;
    expiredAt: string | null;
    lastDeclinedAt: string | null;
    lastRequestedAt: string | null;
};

declare type PortingAddress = {
    city: string;
    country: string;
    line1: string;
    line2: string | null;
    postalCode: string;
    state: string | null;
};

/**
 * Initializes an embed to complete a porting (port-in a number). Requires an
 * authenticated ConnectSession. After initialization, the embed can be mounted
 * into your document.
 *
 * @example
 * const embed = await PortingEmbed(connectSession, { project: 'my-project' })
 * // hide your loading states
 * embed.mount('#embed')
 *
 * @param connectSession An authenticated ConnectSession with an intent type of
 * "completePorting".
 * @param options Initialization options.
 */
export declare function PortingEmbed(initConnectSession: unknown, { options: initialOptions, project, }: {
    /** Additional options to configure the behavior of the embed. */
    options?: PortingEmbedOptions;
} & PortingEmbedInit): Promise<{
    /**
     * Mount the embed into a container.
     *
     * @example
     * embed.mount('#embed')
     *
     * @example
     * embed.mount(document.getElementById('embed'))
     *
     * @param container The HTML Element or selector in which the embed should be
     * mounted to.
     */
    mount(container: Element | string): void;
    /**
     * Update the mounted embed with new options.
     *
     * @example
     * embed.update({ styleOptions: { ... }})
     *
     * @param newOptions New options for the embed
     */
    update(newOptions: PortingEmbedOptions): void;
    /**
     * Unmount the mounted embed.
     *
     * @example
     * embed.unmount()
     */
    unmount(): void;
    /** Add an event listener. */
    on: {
        <Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
        (type: "*", handler: WildcardHandler<Events>): void;
    };
    /** Remove event listener. */
    off: {
        <Key_1 extends keyof Events>(type: Key_1, handler?: Handler<Events[Key_1]> | undefined): void;
        (type: "*", handler: WildcardHandler<Events>): void;
    };
    /**
     * Get the current step in the number porting wizard.
     *
     * @example
     * const step = embed.currentStep()
     *
     * @returns Name of the current step, one of: `"holderDetails"`, `"carrierDetails"`,
     *  `"address"`, `"donorProviderApprovale", or `null`. `null` means there are
     *   no steps anymore.
     */
    currentStep(): "address" | "donorProviderApproval" | "carrierDetails" | "holderDetails" | null;
}>;

declare type PortingEmbedInit = {
    /** The ID of your Gigs project. */
    project: string;
};

export declare type PortingEmbedInstance = Awaited<ReturnType<typeof PortingEmbed>>;

export declare type PortingEmbedOptions = CustomizableEmbedProps;

export declare type PortingEmbedStep = ReturnType<typeof wizardStep>;

declare type PortingRequiredField = 'accountNumber' | 'accountPin' | 'address' | 'birthday' | 'donorProvider' | 'donorProviderApproval' | 'firstName' | 'lastName';

declare type PortingStatus = 'draft' | 'pending' | 'informationRequired' | 'requested' | 'declined' | 'completed' | 'canceled' | 'expired';

declare type ServiceProvider = {
    object: 'serviceProvider';
    id: string;
    name: string;
    recipientProviders: string[];
};

declare type StepChangeEvent = {
    prevStep: PortingEmbedStep;
    nextStep: PortingEmbedStep;
};

declare type SubmitStatusEvent = {
    status: 'loading';
} | {
    status: 'success';
    porting: Porting;
} | {
    status: 'error';
    error: unknown;
};

declare type ValidationChangeEvent = {
    isValid: boolean;
};

declare type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;

declare function wizardStep(porting: Porting): "address" | "donorProviderApproval" | "carrierDetails" | "holderDetails" | null;

export { }
