import { AnalyticsPlugin, PageData } from 'analytics';
export { AnalyticsPlugin } from 'analytics';

type AnalyticsConfig = {
    app?: string;
    version?: string | number;
    debug?: boolean;
    plugins?: AnalyticsPlugin[];
};
type AnyPayload = Record<string, any>;

/**
 * Type-safe wrapper on top of "[analytics](https://www.npmjs.com/package/analytics)" npm package
 * with support of group method (Posthog inspired) to group users into cohorts
 *
 * @example Init analytics in your app with type-guards
 * import { Analytics } from '@open-condo/miniapp-utils/helpers/analytics'
 * import { isDebug } from '@open-condo/miniapp-utils/helpers/environment'
 *
 * type MyAppEvents = {
 *     'order_create': { orderId: string, itemIds: Array<string> }
 *     'user_register': { userId: string, utmSource?: string  }
 * }
 *
 * type MyUserData = {
 *     'name'?: string
 *     'age'?: number
 * }
 *
 * type MyAppGroups = 'organization' | 'country'
 *
 * export const analytics = new Analytics<MyAppEvents, MyUserData, MyAppGroups>({
 *     app: appName,
 *     version: revision,
 *     debug: isDebug(),
 * })
 *
 * @example Use initialized analytics in your-app
 * import { Router } from 'next/router'
 * import { useEffect } from 'react'
 *
 * import { isValidCondoUIMessage } from '@open-condo/ui/events'
 *
 * import { analytics } from '@/domains/common/utils/analytics'
 * import { useAuth } from '@/domains/user/utils/auth'
 *
 * import type { FC } from 'react'
 *
 * export const ResidentAppEventsHandler: FC = () => {
 *     const user = useAuth()
 *     const { activeResident } = useActiveResident()
 *
 *     // User change tracking
 *     useEffect(() => {
 *         if (user) {
 *             analytics.identify(user.id, { name: user.name, type: user.type })
 *         }
 *     }, [user])
 *
 *     // Page views tracking
 *     useEffect(() => {
 *         const handleRouteChange = () => analytics.pageView()
 *         Router.events.on('routeChangeComplete', handleRouteChange)
 *
 *         return () => {
 *             Router.events.off('routeChangeComplete', handleRouteChange)
 *         }
 *     }, [])
 *
 *     // Condo UI events tracking
 *     useEffect(() => {
 *         if (typeof window !== 'undefined') {
 *             const handleMessage = async (e: MessageEvent) => {
 *                 if (isValidCondoUIMessage(e)) {
 *                     const { params: { event, ...eventData } } = e.data
 *                     await analytics.trackUntyped(event, eventData)
 *                 }
 *
 *             }
 *
 *             window.addEventListener('message', handleMessage)
 *
 *             return () => {
 *                 window.removeEventListener('message', handleMessage)
 *             }
 *         }
 *     }, [])
 *
 *     return null
 * }
 */
declare class Analytics<Events extends Record<string, AnyPayload> = Record<string, never>, UserData extends AnyPayload = Record<string, never>, GroupNames extends string = never> {
    private readonly _analytics;
    private readonly _groups;
    constructor(config: AnalyticsConfig);
    /**
     * Tracks type-safe business events. Recommended to use in most cases in app's codebase.
     * To add an event, modify "Events" generic.
     */
    track<EventName extends Extract<keyof Events, string>>(eventName: EventName, eventData: Events[EventName]): Promise<void>;
    /**
     * Tracks untyped analytics events, used mainly for external sources (bridge / ui-kit / messages, etc.)
     * @deprecated It's not recommended to use this in your business logic, consider using typed "track" instead
     */
    trackUntyped(eventName: string, eventData: AnyPayload): Promise<void>;
    /**
     * Tracks page changing in SPAs
     */
    pageView(data?: PageData): Promise<void>;
    /**
     * Identifies user in analytics provider.
     * To specify all possible shape of user's data, modify "UserData" generic
     *
     * NOTE: Analytics plugins don't have a fixed behavior on how to handle consecutive identify calls.
     * Some of them affect only subsequent events, others affect all user events.
     * Therefore, it is not recommended to put cohort-specific data (organization, address, language, etc.) here.
     * Instead, use something like "group" method if your plugins supports it.
     */
    identify<Key extends keyof UserData>(userId: string, userData?: Pick<UserData, Key>): Promise<void>;
    /**
     * Resets analytics providers
     */
    reset(): Promise<void>;
    static getGroupKey(groupName: string): string;
    /**
     * Associates the user with a group, adding the attributes `groups.${groupName} = groupId`
     * to all subsequent analytic queries for the user
     * @example
     * analytics.setGroup('organization', organizationId)
     */
    setGroup(groupName: GroupNames, groupId: string): void;
    /**
     * Removes the current user from the group, stripping the “groups.${groupName}”
     * attribute from all subsequent eventualities
     * @example
     * deleteOrganization()
     *     .then(() => analytics.removeGroup('organization'))
     */
    removeGroup(groupName: GroupNames): void;
}

export { Analytics, type AnalyticsConfig };
