import type { SyntheticEvent } from 'react';
import type { ISettings } from './config';
import type { IMedia } from './media';
/**
 * DOM event wrapper for widget events
 * Contains the original native event from React
 */
export interface DOMEvent {
    /** The original native event from React */
    originalEvent: SyntheticEvent['nativeEvent'];
}
/**
 * Event containing a post (UGC media)
 */
export interface PostEvent {
    /** The media post involved in the event */
    post: IMedia;
}
/**
 * Event containing a media position (e.g., carousel index)
 */
export interface MediaPosition {
    /** Position index of the media */
    position: number;
}
/**
 * Event containing a product identifier
 */
export interface ProductEvent {
    /** Product identifier involved in the event */
    product: string;
}
/**
 * Carousel direction (left or right)
 */
export type Direction = 'left' | 'right';
/**
 * Arrow size for carousel navigation
 */
export type ArrowSize = 'nano' | 'micro' | 'small' | 'compact' | 'medium' | 'large';
/**
 * Carousel scroll event, triggered by arrow or native scroll
 */
export interface CarouselScrollEvent {
    /** Position index after scroll */
    position: number;
    /** Direction of scroll */
    direction: Direction;
}
/**
 * Post navigation event, triggered by arrow keys or swipe
 */
export interface PostNavigationEvent {
    /** Direction of navigation */
    direction: Direction;
    /** The media post navigated to */
    post: IMedia;
}
/**
 * Event for minimum content reached or not reached
 */
export interface MinContentEvent {
    /** Required minimum content count */
    required: number;
    /** Current content count */
    current: number;
}
/**
 * Widget layout event, describes the current layout type
 */
export interface LayoutEvent {
    /** Layout type of the widget */
    layout: ISettings['type'];
}
/**
 * All widget events and their payloads
 */
export interface EventMap {
    /**
     * The widget has finished loading
     * Contains elapsed time and loaded posts
     */
    widgetLoaded: {
        /** Seconds elapsed during loading */
        elapsedSeconds?: number;
        /** List of loaded media posts */
        posts: IMedia[];
    } & LayoutEvent;
    /**
     * The widget has been displayed to the user
     * Emitted only once when the widget is visible in the viewport for at least 0.5 seconds
     */
    widgetViewed: LayoutEvent;
    /**
     * The user has genuinely engaged with the widget.
     * Fires once when BOTH conditions are met:
     *   1. The widget has been continuously visible in the viewport for at least 1 second.
     *   2. The bottom of the widget has been visible at least once.
     */
    widgetObserved: LayoutEvent;
    /**
     * The widget failed to load
     */
    widgetLoadingFailed: Record<string, never>;
    /**
     * A thumbnail has been loaded
     */
    thumbnailLoaded: PostEvent & DOMEvent;
    /**
     * A thumbnail image could not be loaded
     */
    thumbnailUnavailable: PostEvent & DOMEvent;
    /**
     * The mouse hovers a thumbnail
     */
    thumbnailHover: PostEvent & DOMEvent;
    /**
     * A thumbnail has been viewed (at least 50% visible in the viewport)
     * Fires once per unique media per widget session
     */
    thumbnailViewed: PostEvent & MediaPosition;
    /**
     * A thumbnail has been clicked
     */
    thumbnailClicked: PostEvent & DOMEvent & MediaPosition;
    /**
     * The original post has been opened by clicking on the content
     */
    originalPostOpened: PostEvent & DOMEvent;
    /**
     * The social profile page has been opened by clicking on the username
     */
    socialProfileOpened: PostEvent & DOMEvent;
    /**
     * A packshot (product image) has been clicked
     */
    packshotClicked: PostEvent & DOMEvent & ProductEvent;
    /**
     * A post has been opened (when Shop This Look is disabled)
     */
    postOpened: PostEvent;
    /**
     * Change the viewed post by pressing left/right or clicking arrows
     * (when Shop This Look is disabled)
     */
    postNavigation: PostNavigationEvent;
    /**
     * An opened post has been closed (when Shop This Look is disabled)
     */
    postClosed: PostEvent;
    /**
     * The Shop This Look (product list or modal) has been opened
     */
    stlOpened: PostEvent;
    /**
     * Change the viewed post and Shop This Look section by pressing left/right or clicking arrows
     */
    stlNavigation: PostNavigationEvent;
    /**
     * A product from Shop This Look has been viewed
     */
    productViewed: PostEvent & ProductEvent;
    /**
     * A product from Shop This Look has been clicked
     */
    productClicked: PostEvent & DOMEvent & ProductEvent;
    /**
     * The Shop This Look (product list or modal) has been closed
     */
    stlClosed: PostEvent;
    /**
     * The mobile player has been opened
     */
    mobilePlayerOpened: PostEvent;
    /**
     * Change the viewed post by tapping or swiping left/right in mobile player mode
     */
    mobilePlayerNavigation: PostNavigationEvent;
    /**
     * The mobile player has been closed
     */
    mobilePlayerClosed: PostEvent;
    /**
     * The video of the opened post is played
     */
    videoPlayed: PostEvent & DOMEvent;
    /**
     * Scroll the carousel by using the arrows
     */
    carouselArrowClicked: CarouselScrollEvent & DOMEvent;
    /**
     * Scroll the carousel by using the horizontal bar
     */
    carouselNativeScroll: CarouselScrollEvent & DOMEvent;
    /**
     * Not enough content for the required min_media_to_display value
     */
    minContentNotReached: MinContentEvent;
    /**
     * Enough content for the required min_media_to_display value
     */
    minContentReached: MinContentEvent;
}
/**
 * Keys of all widget events
 */
export type EventMapKeys = keyof EventMap;
/**
 * Callback for a widget event
 */
export type EventCallback<T> = (event: T) => void;
/**
 * List of event callbacks
 */
export type EventCallbacks<T> = Array<EventCallback<T>>;
/**
 * Widget event subscription interface
 * Allows subscribing, unsubscribing, and triggering widget events
 */
export interface IWidgetEvents {
    /** Add a callback to listen to an event (previously added callbacks won't be overwritten) */
    onEvent<EventName extends EventMapKeys>(eventName: EventName, callback: EventCallback<EventMap[EventName]>): void;
    /** Remove a callback previously listening to an event */
    offEvent<EventName extends EventMapKeys>(eventName: EventName, callback?: EventCallback<EventMap[EventName]>): void;
    /** Trigger an event programmatically */
    triggerEvent<EventName extends EventMapKeys>(eventName: EventName, event: EventMap[EventName], widgetId?: string): void;
    /** Check if any callback is subscribed to an event */
    hasSubscribed(eventName: EventMapKeys): boolean;
    /** Destroy all event subscriptions for the widget */
    destroy(): void;
}
