import type { AppointmentResourceId, AppointmentServiceId, Brand, CustomerPassId, FormId, PassId, SiteId } from "../../../../../core/src/index";
import type { BlockApiConfig, EligibleAppointmentPackage } from "../api/types";
import type { TimeSlot } from "../api/types";
import type { BookingFormConfig, BookingFormData, BookingFormField, BookingPaymentStepResolution, BookingFormServicesSource, BookingFormService, BookingSelectedCollectionOptionKind, BookingSubmissionData } from "./booking-form.state";
export type LoadState<T> = Readonly<{
    tag: "idle";
}> | Readonly<{
    tag: "loading";
}> | Readonly<{
    tag: "loaded";
    value: T;
}> | Readonly<{
    tag: "error";
    message: string;
}>;
export type BookingFlowStepId = "service-selection" | "datetime-selection" | "payment-selection" | "custom-fields";
export type BookingFlowStepState = "complete" | "active" | "available" | "blocked" | "hidden";
export type BookingFlowStep = Readonly<{
    id: BookingFlowStepId;
    label: string;
    state: BookingFlowStepState;
    index: number;
    visibleIndex: number | null;
    errors: BookingValidationErrors;
    canEnter: boolean;
    canLeave: boolean;
}>;
export type BookingValidationErrors = Readonly<{
    formError: string | null;
    fieldErrors: Readonly<Record<string, string>>;
}>;
export type BookingFieldId = Brand<string, "BookingFieldId">;
export declare const asBookingFieldId: (id: string) => BookingFieldId;
export type BookingFieldValue = string | number | boolean | readonly string[] | null;
export type BookingSlotView = Readonly<{
    key: string;
    startAt: string;
    endAt: string;
    resourceId: AppointmentResourceId;
    resourceName?: string;
    label?: string;
}>;
export type BookingSlotSelection = Readonly<{
    startAt: string;
    endAt: string;
    resourceId: string;
    resourceName?: string;
    label?: string;
}>;
export type BookingResourceView = Readonly<{
    id: AppointmentResourceId;
    label: string;
}>;
export type BookingFlowFeedback = Readonly<{
    kind: "none";
}> | Readonly<{
    kind: "success";
    message: string;
    resourceName: string | null;
}> | Readonly<{
    kind: "error";
    scope: "submission" | "verification" | "discount" | "altcha" | "availability" | "payment";
    message: string;
}> | Readonly<{
    kind: "info";
    scope: "verification" | "payment";
    message: string;
}>;
export type AvailabilitySelectionInvalidation = Readonly<{
    kind: "preserve";
}> | Readonly<{
    kind: "date_unavailable";
    message: string;
}> | Readonly<{
    kind: "slot_unavailable";
    message: string;
}>;
export type BookingFlowStatus = Readonly<{
    tag: "ready";
}> | Readonly<{
    tag: "submitting";
}> | Readonly<{
    tag: "success";
    resourceName: string | null;
}> | Readonly<{
    tag: "error";
    message: string;
}>;
export type BookingFlowView = Readonly<{
    kind: "missing";
    message: string;
}> | Readonly<{
    kind: "form";
}> | Readonly<{
    kind: "success";
    message: string;
    resourceName: string | null;
}> | Readonly<{
    kind: "error";
    message: string;
}>;
export type BookingFlowActionResult = Readonly<{
    ok: true;
}> | Readonly<{
    ok: false;
    reason: "validation-failed";
    errors: BookingValidationErrors;
}> | Readonly<{
    ok: false;
    reason: "blocked";
    message: string;
}> | Readonly<{
    ok: false;
    reason: "submission-failed";
    message: string;
}>;
export type BookingSubmitOptions = Readonly<{
    /**
     * Checkout return URLs apply only to standard paid bookings. Appointment
     * package submissions complete directly through the portal booking API and
     * intentionally ignore these URLs.
     */
    redirect?: "manual" | "auto";
    successUrl?: string;
    cancelUrl?: string;
}>;
export type BookingSubmitActionResult = Readonly<{
    ok: true;
    outcome: {
        kind: "booked";
        appointmentId: string;
        resourceName: string | null;
    };
}> | Readonly<{
    ok: true;
    outcome: {
        kind: "checkout_redirect";
        checkoutUrl: string;
    };
}> | Exclude<BookingFlowActionResult, Readonly<{
    ok: true;
}>>;
export type BookingFieldView = Readonly<{
    field: BookingFormField;
    id: BookingFieldId;
    label: string;
    type: BookingFormField["type"];
    value: BookingFieldValue;
    required: boolean;
    error: string | null;
    helpText: string | null;
    inputId: string;
    labelId: string;
    helpTextId: string | null;
    errorId: string | null;
    describedBy: string | undefined;
    ariaInvalid: boolean;
}>;
export type BookingFlowReducerState = Readonly<{
    currentStepId: BookingFlowStepId;
    selectedServiceId?: AppointmentServiceId;
    selectedResourceId?: AppointmentResourceId;
    selectedDate?: string;
    selectedSlot: BookingSlotView | null;
    fieldValues: Readonly<Record<string, BookingFieldValue>>;
    touchedFields: Readonly<Record<string, boolean>>;
    discountCode: string;
    selectedCollectionOptionKind?: BookingSelectedCollectionOptionKind;
    selectedAppointmentPackageId?: CustomerPassId;
    altchaSolution: string | null;
    validationErrors: BookingValidationErrors;
    feedback: BookingFlowFeedback;
    isSubmitting: boolean;
}>;
export type BookingFlowEvent = Readonly<{
    type: "service-selected";
    serviceId: AppointmentServiceId;
}> | Readonly<{
    type: "resource-selected";
    resourceId: AppointmentResourceId | null;
}> | Readonly<{
    type: "date-selected";
    date: string | null;
}> | Readonly<{
    type: "slot-selected";
    slot: BookingSlotView | null;
}> | Readonly<{
    type: "field-updated";
    fieldId: BookingFieldId;
    value: BookingFieldValue;
}> | Readonly<{
    type: "field-touched";
    fieldId: BookingFieldId;
}> | Readonly<{
    type: "payment-option-selected";
    kind: BookingSelectedCollectionOptionKind | null;
}> | Readonly<{
    type: "appointment-package-selected";
    packageId: CustomerPassId | null;
}> | Readonly<{
    type: "discount-code-changed";
    code: string;
}> | Readonly<{
    type: "altcha-solution-set";
    solution: string | null;
}> | Readonly<{
    type: "altcha-solution-invalidated";
}> | Readonly<{
    type: "step-changed";
    stepId: BookingFlowStepId;
}> | Readonly<{
    type: "validation-errors-set";
    errors: BookingValidationErrors;
}> | Readonly<{
    type: "feedback-set";
    feedback: BookingFlowFeedback;
}> | Readonly<{
    type: "availability-selection-invalidated";
    invalidation: Exclude<AvailabilitySelectionInvalidation, {
        kind: "preserve";
    }>;
}> | Readonly<{
    type: "feedback-cleared";
}> | Readonly<{
    type: "submission-started";
}> | Readonly<{
    type: "submission-finished";
}> | Readonly<{
    type: "reset";
    initial: BookingFlowReducerState;
}>;
export type BuildBookingStepPlanInput = Readonly<{
    form: BookingFormConfig | null;
    services: readonly BookingFormService[];
    data: Partial<BookingFormData>;
    defaultServiceId?: AppointmentServiceId;
    defaultResourceId?: AppointmentResourceId;
    requiresServiceSelection?: boolean;
    requiresResourceSelection?: boolean;
    enableAppointmentPackages?: boolean;
}>;
export type BookingStepPlanItem = Readonly<{
    id: BookingFlowStepId;
    label: string;
    visible: boolean;
}>;
export type BookingStepValidationResult = Readonly<{
    ok: true;
}> | Readonly<{
    ok: false;
    errors: BookingValidationErrors;
}>;
export type DeriveBookingFlowStepsInput = Readonly<{
    form: BookingFormConfig | null;
    services: readonly BookingFormService[];
    data: Partial<BookingFormData>;
    defaultServiceId?: AppointmentServiceId;
    defaultResourceId?: AppointmentResourceId;
    currentStepId: BookingFlowStepId;
    requiresServiceSelection?: boolean;
    requiresResourceSelection?: boolean;
    enableAppointmentPackages?: boolean;
}>;
export type DerivedBookingFlowSteps = Readonly<{
    steps: readonly BookingFlowStep[];
    currentStepIndex: number;
    currentStep: BookingFlowStep | null;
    stepIds: readonly BookingFlowStepId[];
    validations: ReadonlyMap<BookingFlowStepId, BookingStepValidationResult>;
}>;
export type BookingAvailabilityQuery = Readonly<{
    ok: true;
    key: string;
    serviceId: AppointmentServiceId;
    resourceId?: AppointmentResourceId;
    selectedDate?: string;
    timezone: string;
}> | Readonly<{
    ok: false;
    reason: "missing-service" | "missing-date";
    key: string;
}>;
export type BookingSubmitRedirectMode = "manual" | "auto";
export type BookingSubmitPlan = Readonly<{
    ok: true;
    redirect: BookingSubmitRedirectMode;
    value: BookingSubmissionData;
}> | Readonly<{
    ok: false;
    errors: BookingValidationErrors;
    message: string;
}>;
export type BookingAppointmentPackagesModel = Readonly<{
    kind: "disabled";
    enabled: false;
    canLoad: false;
    unavailableReason: "disabled";
    state: Readonly<{
        tag: "idle";
    }>;
    items: readonly [];
    selected: null;
}> | Readonly<{
    kind: "unavailable";
    enabled: true;
    canLoad: false;
    unavailableReason: "missing-portal-auth" | "missing-priced-service";
    state: Readonly<{
        tag: "idle";
    }>;
    items: readonly [];
    selected: null;
}> | Readonly<{
    kind: "idle";
    enabled: true;
    canLoad: true;
    unavailableReason: null;
    state: Readonly<{
        tag: "idle";
    }>;
    items: readonly [];
    selected: null;
}> | Readonly<{
    kind: "loading";
    enabled: true;
    canLoad: true;
    unavailableReason: null;
    state: Readonly<{
        tag: "loading";
    }>;
    items: readonly [];
    selected: null;
}> | Readonly<{
    kind: "error";
    enabled: true;
    canLoad: true;
    unavailableReason: null;
    state: Readonly<{
        tag: "error";
        message: string;
    }>;
    items: readonly [];
    selected: null;
}> | Readonly<{
    kind: "ready";
    enabled: true;
    canLoad: true;
    unavailableReason: null;
    state: Readonly<{
        tag: "loaded";
        value: readonly HeadlessEligibleAppointmentPackage[];
    }>;
    items: readonly HeadlessEligibleAppointmentPackage[];
    selected: HeadlessEligibleAppointmentPackage | null;
}>;
export type BookingAppointmentPackagesUnavailableReason = "disabled" | "missing-portal-auth" | "missing-priced-service";
export type AppointmentBookingOverrideData = Readonly<{
    form?: BookingFormConfig | Record<string, unknown> | null;
    services?: BookingFormServicesSource | Record<string, unknown> | null;
}>;
export type AppointmentBookingOverrideContent = Readonly<{
    formId?: string;
    serviceId?: string;
    resourceId?: string;
    requiresServiceSelection?: boolean;
    requiresResourceSelection?: boolean;
    shouldAutoSelectSingleResource?: boolean;
    spamProtectionEnabled?: boolean;
    successMessage?: string;
}>;
export type AppointmentBookingOverridePropsLike = Readonly<{
    content?: AppointmentBookingOverrideContent | null;
    data?: AppointmentBookingOverrideData | Record<string, unknown> | null;
    siteId?: string;
    apiBaseUrl?: string;
    portalToken?: string | null;
    blockId?: string | null;
}>;
export type AppointmentBookingOverrideInput = Readonly<{
    siteId: SiteId;
    apiBaseUrl: string;
    portalToken: string | null;
    formId: FormId;
    form: BookingFormConfig;
    services: readonly BookingFormService[];
    initialServiceId?: AppointmentServiceId;
    initialResourceId?: AppointmentResourceId;
    requiresServiceSelection: boolean;
    requiresResourceSelection: boolean;
    shouldAutoSelectSingleResource: boolean;
    spamProtectionEnabled?: boolean;
    successMessage?: string;
    blockId?: string | null;
}>;
export type HeadlessEligibleAppointmentPackage = Omit<EligibleAppointmentPackage, "customerPassId" | "passId"> & Readonly<{
    customerPassId: CustomerPassId;
    passId: PassId;
}>;
export type AppointmentBookingOverrideInputResult = Readonly<{
    ok: true;
    value: AppointmentBookingOverrideInput;
}> | Readonly<{
    ok: false;
    reason: "missing-site-id" | "missing-api-base-url" | "missing-form" | "missing-form-id" | "missing-services";
    message: string;
}>;
export declare function createEmptyBookingValidationErrors(): BookingValidationErrors;
export declare function createFormBookingValidationError(formError: string): BookingValidationErrors;
export declare function createFieldBookingValidationErrors(fieldErrors: Readonly<Record<string, string>>): BookingValidationErrors;
export declare function hasBookingValidationErrors(errors: BookingValidationErrors): boolean;
export declare function createInitialBookingFlowReducerState(input: Readonly<{
    defaultServiceId?: string;
    defaultResourceId?: string;
    initialData?: Partial<BookingFormData>;
}>): BookingFlowReducerState;
export declare function toOptionalAppointmentServiceId(value: string | undefined): AppointmentServiceId | undefined;
export declare function toOptionalAppointmentResourceId(value: string | undefined): AppointmentResourceId | undefined;
export declare function bookingFlowReducer(state: BookingFlowReducerState, event: BookingFlowEvent): BookingFlowReducerState;
export declare function resolveAvailabilitySelectionInvalidation(input: Readonly<{
    selectedDate?: string;
    selectedSlot: BookingSlotView | null;
    availableDates: readonly string[];
    slots: readonly BookingSlotView[];
}>): AvailabilitySelectionInvalidation;
export declare function toBookingSlotView(slot: BookingSlotSelection): BookingSlotView;
export declare function toBookingSlotViews(slots: readonly TimeSlot[]): BookingSlotView[];
export declare function toBookingFormData(state: BookingFlowReducerState): BookingFormData;
export declare function buildBookingStepPlan(input: BuildBookingStepPlanInput): readonly BookingStepPlanItem[];
export declare function validateBookingStep(input: Readonly<{
    stepId: BookingFlowStepId;
    form: BookingFormConfig | null;
    services: readonly BookingFormService[];
    data: Partial<BookingFormData>;
    defaultServiceId?: string;
    defaultResourceId?: string;
    requiresResourceSelection?: boolean;
    paymentResolution?: BookingPaymentStepResolution;
}>): BookingStepValidationResult;
export declare function validateBookingFields(input: Readonly<{
    fields: readonly BookingFormField[];
    values: Readonly<Record<string, unknown>>;
}>): Record<string, string>;
export declare function validateBookingField(field: BookingFormField, value: unknown): string | null;
export declare function deriveBookingFlowSteps(input: DeriveBookingFlowStepsInput): DerivedBookingFlowSteps;
export declare function buildBookingAvailabilityQuery(input: Readonly<{
    serviceId?: AppointmentServiceId;
    resourceId?: AppointmentResourceId;
    selectedDate?: string;
    timezone: string;
    requireDate?: boolean;
}>): BookingAvailabilityQuery;
export declare function deriveBookingFieldViews(input: Readonly<{
    form: BookingFormConfig | null;
    values: Readonly<Record<string, BookingFieldValue>>;
    errors: Readonly<Record<string, string>>;
    touched?: Readonly<Record<string, boolean>>;
    idPrefix: string;
}>): readonly BookingFieldView[];
export declare function buildBookingSubmitPlan(input: Readonly<{
    formId: FormId;
    form: BookingFormConfig | null;
    state: BookingFlowReducerState;
    services: readonly BookingFormService[];
    defaultServiceId?: AppointmentServiceId;
    defaultResourceId?: AppointmentResourceId;
    requiresResourceSelection?: boolean;
    altchaSolution?: string | null;
    viewerTimeZone: string;
    redirect: BookingSubmitRedirectMode;
    successUrl?: string;
    cancelUrl?: string;
}>): BookingSubmitPlan;
export declare function getAppointmentBookingOverrideInput(props: AppointmentBookingOverridePropsLike): AppointmentBookingOverrideInputResult;
export declare function createBookingBlockApiConfig(input: Readonly<{
    siteId: string;
    apiBaseUrl: string;
    portalToken?: string | null;
}>): BlockApiConfig;
export declare function resolveHeadlessBookingSelectedService(input: Readonly<{
    state: BookingFlowReducerState;
    services: readonly BookingFormService[];
    defaultServiceId?: string;
}>): BookingFormService | null;
export declare function resolveAppointmentPackagesModel(input: Readonly<{
    enabled: boolean;
    canLoad: boolean;
    unavailableReason: BookingAppointmentPackagesUnavailableReason | null;
    state: LoadState<readonly EligibleAppointmentPackage[]>;
    items: readonly EligibleAppointmentPackage[];
    selected: EligibleAppointmentPackage | null;
}>): BookingAppointmentPackagesModel;
export declare function resolveHeadlessBookingStatus(input: Readonly<{
    feedback: BookingFlowFeedback;
    isSubmitting: boolean;
}>): BookingFlowStatus;
export declare function resolveHeadlessBookingView(input: Readonly<{
    form: BookingFormConfig | null;
    feedback: BookingFlowFeedback;
}>): BookingFlowView;
export declare function describeUnknownError(error: unknown, fallback: string): string;
