import * as react from 'react';
import { JSX, ReactNode } from 'react';

/**
 * Theme configuration for the Tebuto Booking Widget.
 * All colors should be valid CSS color strings (e.g., '#00B4A9', 'rgb(0, 180, 169)').
 *
 * Note: The widget automatically generates color variations (light, dark, etc.)
 * from the primaryColor, so only the base colors need to be configured.
 */
type TebutoWidgetTheme = {
    /** Primary brand color - used for buttons, highlights, selected states */
    primaryColor?: string;
    /** Main widget background color */
    backgroundColor?: string;
    /** Main text color */
    textPrimary?: string;
    /** Secondary/muted text color */
    textSecondary?: string;
    /** General border color */
    borderColor?: string;
    /** Widget font family */
    fontFamily?: string;
    /** Inherit font from parent page instead of using widget font */
    inheritFont?: boolean;
};
/**
 * Configuration options for the Tebuto Booking Widget.
 */
type TebutoBookingWidgetConfiguration = {
    /** UUID of the therapist whose calendar should be displayed (required) */
    therapistUUID: string;
    /** Background color of the widget (shorthand for theme.backgroundColor) */
    backgroundColor?: string;
    /** Array of category IDs to filter available appointments */
    categories?: number[];
    /** Whether to display a border around the widget (default: true) */
    border?: boolean;
    /** Include subuser appointments in the calendar (default: false) */
    includeSubusers?: boolean;
    /** Show quick filter buttons for time slots (default: false) */
    showQuickFilters?: boolean;
    /** Inherit font from parent page instead of using widget font (default: false) */
    inheritFont?: boolean;
    /** Theme configuration for customizing colors and fonts */
    theme?: TebutoWidgetTheme;
};

type TebutoBookingWidgetProps = {
    noScriptText?: string;
} & TebutoBookingWidgetConfiguration;
declare function TebutoBookingWidget({ noScriptText, ...config }: TebutoBookingWidgetProps): JSX.Element;

type CustomBookingExampleProps = {
    therapistUUID: string;
    categories?: number[];
};
/**
 * CustomBookingExample - A modern, fully-featured booking interface
 *
 * This example demonstrates how to use the Tebuto hooks to build
 * a completely custom booking experience.
 *
 * @example
 * ```tsx
 * import { CustomBookingExample } from '@tebuto/react-booking-widget'
 *
 * function BookingPage() {
 *   return <CustomBookingExample therapistUUID="your-uuid" />
 * }
 * ```
 */
declare function CustomBookingExample({ therapistUUID, categories }: Readonly<CustomBookingExampleProps>): react.JSX.Element;

/**
 * API Types for Tebuto Booking Hooks
 * These types represent the data structures returned by the Tebuto API.
 */
/** Location type for appointments */
type AppointmentLocation = 'virtual' | 'onsite' | 'not-fixed';
/** Address structure for therapist/location */
type Address = {
    streetAndNumber: string;
    additionalInformation?: string;
    city: {
        name: string;
        zip: string;
    };
};
/** Therapist information */
type Therapist = {
    name: string;
    firstName: string;
    lastName: string;
    address: Address;
    showWatermark: boolean;
};
/** Therapist reference in events */
type TherapistReference = {
    id: number;
    uuid: string;
    name: string;
};
/** Available time slot / event */
type TimeSlot = {
    title: string;
    start: string;
    end: string;
    location: AppointmentLocation;
    color: string;
    price: string;
    taxRate: string;
    outageFeeEnabled: boolean;
    outageFeeHours: number;
    outageFeePrice: number;
    eventRuleId: number;
    eventCategoryId: number;
    paymentEnabled: boolean;
    paymentDuringBooking: boolean;
    therapist: TherapistReference;
};
/** Response from claim endpoint */
type ClaimResponse = {
    isAvailable: boolean;
    requirePhoneNumber: boolean;
    requireAddress: boolean;
    requireBirthdate: boolean;
};
/** Payment configuration */
type PaymentConfiguration = {
    paymentTypes: string[];
    onlinePaymentMethods: string[];
};
/** Client information for booking */
type ClientInfo = {
    firstName: string;
    lastName: string;
    email: string;
    phone?: string;
    address?: {
        streetAndNumber: string;
        additionalInformation?: string;
        city: string;
        zip: string;
    };
    birthdate?: string;
    notes?: string;
};
/** Booking request payload */
type BookingRequest = {
    start: string;
    end: string;
    eventRuleId: number;
    locationSelection: AppointmentLocation;
    client: ClientInfo;
};
/** Booking response */
type BookingResponse = {
    id: number;
    createdAt: string;
    locationSelection: AppointmentLocation;
    isConfirmed: boolean;
    isOutage: boolean;
    ics: string;
};
/** Hook state for async operations */
type AsyncState<T> = {
    data: T | null;
    isLoading: boolean;
    error: Error | null;
};
/** Category for filtering */
type EventCategory = {
    id: number;
    name: string;
    color: string;
    price: string;
    location: AppointmentLocation;
};
/** Grouped time slots by date */
type SlotsByDate = {
    [date: string]: TimeSlot[];
};
/** Time slot with additional computed properties */
type EnrichedTimeSlot = TimeSlot & {
    dateKey: string;
    timeString: string;
    durationMinutes: number;
    formattedPrice: string;
    isToday: boolean;
    isPast: boolean;
};

type TebutoConfig = {
    therapistUUID: string;
    apiBaseUrl: string;
    categories?: number[];
    includeSubusers?: boolean;
};
type TebutoContextValue = TebutoConfig & {
    buildUrl: (path: string) => string;
    fingerprint: string;
};
type TebutoProviderProps = {
    therapistUUID: string;
    apiBaseUrl?: string;
    categories?: number[];
    includeSubusers?: boolean;
    children: ReactNode;
};
/**
 * TebutoProvider - Context provider for Tebuto booking hooks
 *
 * Wrap your booking components with this provider to share configuration
 * across all Tebuto hooks.
 *
 * @example
 * ```tsx
 * <TebutoProvider therapistUUID="your-uuid">
 *   <YourBookingComponent />
 * </TebutoProvider>
 * ```
 */
declare function TebutoProvider({ therapistUUID, apiBaseUrl, categories, includeSubusers, children }: Readonly<TebutoProviderProps>): react.JSX.Element;
/**
 * useTebutoContext - Access the Tebuto configuration context
 *
 * Must be used within a TebutoProvider.
 *
 * @throws Error if used outside of TebutoProvider
 */
declare function useTebutoContext(): TebutoContextValue;

type UseTherapistReturn = AsyncState<Therapist> & {
    refetch: () => Promise<void>;
};
/**
 * useTherapist - Fetch therapist information
 *
 * Automatically fetches the therapist data when the component mounts.
 * Uses the therapistUUID from the TebutoProvider context.
 *
 * @example
 * ```tsx
 * const { data: therapist, isLoading, error } = useTherapist()
 *
 * if (isLoading) return <Spinner />
 * if (error) return <Error message={error.message} />
 *
 * return <h1>Book with {therapist.name}</h1>
 * ```
 */
declare function useTherapist(): UseTherapistReturn;

type UseAvailableSlotsOptions = {
    /** Auto-fetch on mount (default: true) */
    autoFetch?: boolean;
    /** Filter by specific category IDs */
    categories?: number[];
};
type UseAvailableSlotsReturn = AsyncState<TimeSlot[]> & {
    /** Refetch available slots */
    refetch: () => Promise<void>;
    /** Slots grouped by date (YYYY-MM-DD) */
    slotsByDate: SlotsByDate;
    /** All unique dates with available slots */
    availableDates: Date[];
    /** Get enriched slots for a specific date */
    getSlotsForDate: (date: Date) => EnrichedTimeSlot[];
    /** All unique categories from available slots */
    categories: Array<{
        id: number;
        name: string;
        color: string;
    }>;
    /** Total count of available slots */
    totalSlots: number;
};
/**
 * useAvailableSlots - Fetch and manage available time slots
 *
 * Provides available appointment slots with helpers for grouping,
 * filtering, and date navigation.
 *
 * @example
 * ```tsx
 * const {
 *   slotsByDate,
 *   availableDates,
 *   getSlotsForDate,
 *   isLoading
 * } = useAvailableSlots()
 *
 * const [selectedDate, setSelectedDate] = useState<Date | null>(null)
 *
 * return (
 *   <div>
 *     <DatePicker dates={availableDates} onSelect={setSelectedDate} />
 *     {selectedDate && (
 *       <TimeSlotList slots={getSlotsForDate(selectedDate)} />
 *     )}
 *   </div>
 * )
 * ```
 */
declare function useAvailableSlots(options?: UseAvailableSlotsOptions): UseAvailableSlotsReturn;

type ClaimState = {
    claimedSlot: TimeSlot | null;
    claimResponse: ClaimResponse | null;
    isLoading: boolean;
    error: Error | null;
};
type UseClaimSlotReturn = ClaimState & {
    /** Claim a time slot to reserve it temporarily */
    claim: (slot: TimeSlot) => Promise<ClaimResponse | null>;
    /** Release the currently claimed slot */
    unclaim: () => Promise<void>;
    /** Check if a specific slot is currently claimed */
    isClaimed: (slot: TimeSlot) => boolean;
    /** Clear error state */
    clearError: () => void;
};
/**
 * useClaimSlot - Temporarily claim a time slot
 *
 * Claims a time slot to reserve it while the user fills out
 * their booking information. Automatically handles unclaiming
 * when claiming a new slot.
 *
 * @example
 * ```tsx
 * const { claim, unclaim, claimedSlot, claimResponse, isLoading } = useClaimSlot()
 *
 * const handleSlotSelect = async (slot: TimeSlot) => {
 *   const response = await claim(slot)
 *   if (response?.isAvailable) {
 *     setStep('booking-form')
 *   }
 * }
 *
 * const handleCancel = () => {
 *   unclaim()
 *   setStep('slot-selection')
 * }
 * ```
 */
declare function useClaimSlot(): UseClaimSlotReturn;

type BookingRequestState = {
    isLoading: boolean;
    error: Error | null;
    isSuccess: boolean;
};
type BookAppointmentParams = {
    slot: TimeSlot;
    client: ClientInfo;
    locationSelection?: AppointmentLocation;
};
type UseBookAppointmentReturn = BookingRequestState & {
    /** Submit booking request - returns true on success */
    book: (params: BookAppointmentParams) => Promise<boolean>;
    /** Reset the state */
    reset: () => void;
};
/**
 * useBookAppointment - Submit a public booking request
 *
 * Submits a booking request with client information. For public bookings,
 * the client will receive a confirmation email to verify the appointment.
 *
 * @example
 * ```tsx
 * const { book, isLoading, isSuccess, error, reset } = useBookAppointment()
 *
 * const handleSubmit = async (clientInfo: ClientInfo) => {
 *   const success = await book({
 *     slot: claimedSlot,
 *     client: clientInfo,
 *     locationSelection: selectedLocation
 *   })
 *
 *   if (success) {
 *     setStep('confirmation')
 *   }
 * }
 * ```
 */
declare function useBookAppointment(): UseBookAppointmentReturn;

type BookingStep = 'loading' | 'date-selection' | 'time-selection' | 'booking-form' | 'confirmation' | 'error';
type UseBookingFlowOptions = {
    /** Categories to filter by */
    categories?: number[];
    /** Callback when booking request is submitted successfully */
    onBookingComplete?: () => void;
    /** Callback on any error */
    onError?: (error: Error) => void;
};
type UseBookingFlowReturn = {
    /** Current booking step */
    step: BookingStep;
    /** Go to a specific step */
    goToStep: (step: BookingStep) => void;
    /** Therapist information */
    therapist: ReturnType<typeof useTherapist>;
    /** Available slots management */
    slots: ReturnType<typeof useAvailableSlots>;
    /** Selected date */
    selectedDate: Date | null;
    /** Select a date */
    selectDate: (date: Date | null) => void;
    /** Slots for the selected date */
    selectedDateSlots: EnrichedTimeSlot[];
    /** Selected time slot */
    selectedSlot: TimeSlot | null;
    /** Select a time slot (claims it) */
    selectSlot: (slot: TimeSlot | null) => Promise<boolean>;
    /** Selected location (for not-fixed appointments) */
    selectedLocation: AppointmentLocation | null;
    /** Set the location selection */
    setLocation: (location: AppointmentLocation) => void;
    /** Claim state */
    claim: ReturnType<typeof useClaimSlot>;
    /** Booking state */
    booking: ReturnType<typeof useBookAppointment>;
    /** Submit booking with client info */
    submitBooking: (client: ClientInfo) => Promise<boolean>;
    /** Start over from the beginning */
    reset: () => void;
    /** Overall loading state */
    isLoading: boolean;
    /** Current error if any */
    error: Error | null;
};
/**
 * useBookingFlow - Complete booking flow orchestration
 *
 * A convenience hook that combines all booking hooks and manages
 * the booking flow state. Perfect for quickly building a booking UI.
 *
 * @example
 * ```tsx
 * function BookingPage() {
 *   const {
 *     step,
 *     therapist,
 *     slots,
 *     selectedDate,
 *     selectDate,
 *     selectedDateSlots,
 *     selectSlot,
 *     submitBooking,
 *     booking,
 *     reset
 *   } = useBookingFlow()
 *
 *   switch (step) {
 *     case 'loading':
 *       return <LoadingSpinner />
 *
 *     case 'date-selection':
 *       return (
 *         <DatePicker
 *           availableDates={slots.availableDates}
 *           onSelect={selectDate}
 *         />
 *       )
 *
 *     case 'time-selection':
 *       return (
 *         <TimeSlotPicker
 *           slots={selectedDateSlots}
 *           onSelect={selectSlot}
 *         />
 *       )
 *
 *     case 'booking-form':
 *       return (
 *         <BookingForm onSubmit={submitBooking} />
 *       )
 *
 *     case 'confirmation':
 *       return (
 *         <Confirmation
 *           booking={booking.booking}
 *           onReset={reset}
 *         />
 *       )
 *   }
 * }
 * ```
 */
declare function useBookingFlow(options?: UseBookingFlowOptions): UseBookingFlowReturn;

export { CustomBookingExample, TebutoBookingWidget, TebutoProvider, useAvailableSlots, useBookAppointment, useBookingFlow, useClaimSlot, useTebutoContext, useTherapist };
export type { Address, AppointmentLocation, AsyncState, BookingRequest, BookingResponse, ClaimResponse, ClientInfo, EnrichedTimeSlot, EventCategory, PaymentConfiguration, SlotsByDate, TebutoBookingWidgetConfiguration, TebutoWidgetTheme, Therapist, TherapistReference, TimeSlot };
