import { App } from 'vue';
import { Ref } from 'vue';
import { RouteLocationNormalizedGeneric } from 'vue-router';
import { Router as Router_2 } from 'vue-router';

/**
 * Adds the Google Analytics gtag script to the application and initializes router
 * auto-tracking when enabled.
 */
export declare function addGtag(): Promise<void>;

export declare function config(params: GtagConfig): void;

export declare function consent(consentArg: GtagConsentArg, params: GtagConsentParams): void;

export declare function consentDeniedAll(mode?: GtagConsentArg): void;

export declare function consentGrantedAll(mode?: GtagConsentArg): void;

/** Creates and initializes the `gtag` function for use within a Vue application. */
export declare function createGtag(settings: PluginSettings): CreateGtagReturn;

declare type CreateGtagReturn = (app: App) => void;

export declare function customMap(params: GtagCustomParams): void;

export declare function ecommerce(name: GtagEcommerceEventNames, params: GtagEcommerceParams): void;

declare function event_2(name: GtagEventNames, params: EventParams): void;
export { event_2 as event }

declare type EventParams = GtagControlParams & GtagEventParams & GtagCustomParams;

export declare function exception(params: ExceptionParams): void;

declare type ExceptionParams = {
    description?: string;
    fatal?: boolean;
} | GtagCustomParams;

declare type Gtag = <Command extends keyof GtagCommands>(command: Command, ...args: GtagCommands[Command]) => void;

/**
 * Defines the available Google Tag (gtag) commands and their respective parameters.
 */
declare type GtagCommands = {
    /** Configures the Google Tag with an optional set of parameters. */
    config: [
    /** The tracking ID or measurement ID. */
    targetId: string,
    /** Optional configuration parameters. */
    config?: GtagConfig
    ];
    /** Sets custom parameters or updates existing values. */
    set: [targetId: string, config: GtagCustomParams | boolean | string] | [config: GtagCustomParams];
    /** Initializes the Google Tag script. */
    js: [
    /** The date when the script was initialized. */
    config: Date
    ];
    /** Logs an event with optional parameters. */
    event: [
    /** The name of the event being logged. */
    eventName: GtagEventNames | (string & {}),
    /** Optional parameters associated with the event. */
    eventParams?: GtagControlParams | GtagEventParams | GtagCustomParams
    ];
    /** Retrieves values from the Google Tag system. */
    get: [
    /** The tracking ID or measurement ID. */
    targetId: string,
    /** The field name to retrieve. */
    fieldName: GtagFieldNames | string,
    /** Callback function to handle the retrieved value. */
    callback?: (field?: string | GtagCustomParams) => any
    ];
    /** Manages user consent settings. */
    consent: [
    /** The consent action being performed. */
    consentArg: GtagConsentArg | (string & {}),
    /** The consent parameters being updated. */
    consentParams: GtagConsentParams
    ];
};

declare type GtagConfig = GtagControlParams | GtagEventParams | GtagConfigParams | GtagCustomParams;

/**
 * Parameters for configuring Google Analytics tracking.
 */
declare type GtagConfigParams = {
    /** The title of the page being tracked. */
    page_title?: string;
    /** The full URL of the page being tracked. */
    page_location?: string;
    /** The path of the page being tracked. */
    page_path?: string;
    /** Whether to send a page view event automatically. */
    send_page_view?: boolean;
};

declare type GtagConsentArg = "default" | "update";

declare type GtagConsentMode = "granted" | "denied";

declare type GtagConsentParams = {
    /** Consent for ad personalization. */
    ad_personalization?: GtagConsentMode;
    /** Consent for ad user data. */
    ad_user_data?: GtagConsentMode;
    /** Consent for ad storage. */
    ad_storage?: GtagConsentMode;
    /** Consent for analytics storage. */
    analytics_storage?: GtagConsentMode;
    /** Consent for functionality storage. */
    functionality_storage?: GtagConsentMode;
    /** Consent for personalization storage. */
    personalization_storage?: GtagConsentMode;
    /** Consent for security storage. */
    security_storage?: GtagConsentMode;
    /** Time to wait for consent update in milliseconds. */
    wait_for_update?: number;
    /** The regions where the consent applies. */
    region?: string[];
};

/**
 * Control parameters for Google Tag events.
 */
declare type GtagControlParams = {
    /** The groups to which the event belongs. */
    groups?: string | string[];
    /** The tracking IDs to which the event should be sent. */
    send_to?: string | string[];
    /** Callback function executed after the event is sent. */
    event_callback?: () => void;
    /** The timeout in milliseconds before the event callback is executed. */
    event_timeout?: number;
};

declare type GtagCurrency = string | number;

declare type GtagCustomParams = Record<string, any>;

declare type GtagEcommerceEventNames = "refund" | "select_item" | "view_item" | "add_to_cart" | "view_item_list" | "add_shipping_info" | "add_payment_info" | "add_to_wishlist" | "view_cart" | "remove_from_cart" | "begin_checkout" | "purchase" | "view_promotion" | "select_promotion";

declare type GtagEcommerceParams = {
    /** The unique transaction ID (order ID). */
    transaction_id?: string;
    /** The total monetary value of the event. */
    value?: number;
    /** The currency of the transaction, in ISO 4217 3-letter format (e.g., "USD"). */
    currency?: string;
    /** The coupon name/code applied to the event. */
    coupon?: string;
    /** The shipping cost associated with the transaction. */
    shipping?: number;
    /** The total tax amount associated with the transaction. */
    tax?: number;
    /** Array of items associated with the event. */
    items?: GtagItem[];
    /** Payment method used for the transaction (e.g., "Credit Card", "PayPal"). */
    payment_type?: string;
    /**
     * The name of the promotional creative associated with the event.
     * Ignored if set at the item-level.
     */
    creative_name?: string;
    /**
     * The creative slot name associated with the event.
     * Ignored if set at the item-level.
     */
    creative_slot?: string;
    /**
     * The ID of the promotion associated with the event.
     * Ignored if set at the item-level.
     */
    promotion_id?: string;
    /**
     * The name of the promotion associated with the event.
     * Ignored if set at the item-level.
     */
    promotion_name?: string;
};

declare type GtagEventNames = GtagEcommerceEventNames | GtagGeneralEventNames | (string & {});

/**
 * Parameters associated with Google Analytics events.
 */
declare type GtagEventParams = {
    /** The option chosen during checkout. */
    checkout_option?: string;
    /** The step number in the checkout process. */
    checkout_step?: number;
    /** The unique identifier of the content. */
    content_id?: string;
    /** The type of content being interacted with. */
    content_type?: string;
    /** A discount coupon code. */
    coupon?: string;
    /** The currency used for the transaction. */
    currency?: string;
    /** A description of the event or product. */
    description?: string;
    /** Indicates if the event was fatal. */
    fatal?: boolean;
    /** The items associated with the event. */
    items?: GtagItem[];
    /** The payment or shipping method used. */
    method?: string;
    /** A unique number associated with the transaction. */
    number?: string;
    /** The promotions associated with the event. */
    promotions?: GtagPromotion[];
    /** The screen name where the event occurred. */
    screen_name?: string;
    /** The search term used. */
    search_term?: string;
    /** The shipping cost. */
    shipping?: GtagCurrency;
    /** The tax amount. */
    tax?: GtagCurrency;
    /** The transaction ID. */
    transaction_id?: string;
    /** The event value. */
    value?: number;
    /** The label for the event. */
    event_label?: string;
    /** The category for the event. */
    event_category?: string;
};

declare type GtagFieldNames = "client_id" | "session_id" | "gclid";

declare type GtagGeneralEventNames = "checkout_progress" | "earn_virtual_currency" | "exception" | "generate_lead" | "join_group" | "level_end" | "level_start" | "level_up" | "login" | "page_view" | "post_score" | "screen_view" | "search" | "select_content" | "set_checkout_option" | "share" | "sign_up" | "spend_virtual_currency" | "tutorial_begin" | "tutorial_complete" | "unlock_achievement" | "timing_complete" | "view_search_results";

declare type GtagItem = {
    /** The ID of the item. */
    item_id?: string;
    /** The name of the item. */
    item_name?: string;
    /** A product affiliation to designate a supplying company or brick and mortar store location. */
    affiliation?: string;
    /** The coupon name/code associated with the item. */
    coupon?: string;
    /** The unit monetary discount value associated with the item. */
    discount?: number;
    /** The index/position of the item in a list. */
    index?: number;
    /** The brand of the item. */
    item_brand?: string;
    /**
     * The category of the item.
     * If used as part of a category hierarchy or taxonomy then this will be the first category.
     */
    item_category?: string;
    /** The second category hierarchy or additional taxonomy for the item. */
    item_category2?: string;
    /** The third category hierarchy or additional taxonomy for the item. */
    item_category3?: string;
    /** The fourth category hierarchy or additional taxonomy for the item. */
    item_category4?: string;
    /** The fifth category hierarchy or additional taxonomy for the item. */
    item_category5?: string;
    /**
     * The ID of the list in which the item was presented to the user.
     * If set, event-level item_list_id is ignored.
     * If not set, event-level item_list_id is used, if present.
     */
    item_list_id?: string;
    /**
     * The name of the list in which the item was presented to the user.
     * If set, event-level item_list_name is ignored.
     * If not set, event-level item_list_name is used, if present.
     */
    item_list_name?: string;
    /** The item variant or unique code or description for additional item details/options. */
    item_variant?: string;
    /**
     * The physical location associated with the item (e.g. the physical store location).
     * Recommended to use Google Place ID. Custom IDs are allowed.
     * Note: `location_id` is only available at the item-scope.
     */
    location_id?: string;
    /**
     * The monetary unit price of the item, in units of the specified currency.
     * If a discount applies, set this to the discounted unit price and specify the discount separately.
     */
    price?: number;
    /** Item quantity. Defaults to 1 if not set. */
    quantity?: number;
    /**
     * The name of the promotional creative slot associated with the item.
     * If set, event-level creative_slot is ignored.
     */
    creative_slot?: string;
    /**
     * The name of the promotional creative.
     * If set, event-level creative_name is ignored.
     */
    creative_name?: string;
    /**
     * The ID of the promotion associated with the item.
     * If set, event-level promotion_id is ignored.
     */
    promotion_id?: string;
    /**
     * The name of the promotion associated with the item.
     * If set, event-level promotion_name is ignored.
     */
    promotion_name?: string;
};

declare type GtagPromotion = {
    /**
     * The name of the promotional creative.
     * If set, event-level creative_name is ignored.
     */
    creative_name?: string;
    /**
     * The name of the promotional creative slot associated with the item.
     * If set, event-level creative_slot is ignored.
     */
    creative_slot?: string;
    /**
     * The ID of the promotion associated with the item.
     * If set, event-level promotion_id is ignored.
     */
    promotion_id?: string;
    /**
     * The name of the promotion associated with the item.
     * If set, event-level promotion_name is ignored.
     */
    promotion_name?: string;
};

declare type Hooks = {
    /**
     * Triggered before a route tracking event is fired.
     * @param route - The current route being tracked.
     */
    "router:track:before"?: (route: Route) => void;
    /**
     * Triggered after a route tracking event is fired.
     * @param route - The current route that was tracked.
     */
    "router:track:after"?: (route: Route) => void;
    /**
     * Triggered before the initial configuration request is sent.
     */
    "config:init:before"?: () => void;
    /**
     * Triggered after the initial configuration request is sent.
     */
    "config:init:after"?: () => void;
    /**
     * Called when the gtag.js script successfully loads.
     */
    "script:loaded"?: () => void;
    /**
     * Called when the gtag.js script fails to load.
     * @param error - The error encountered during script loading.
     */
    "script:error"?: (error: unknown) => void;
};

export declare function linker(params: LinkerParams): void;

export declare type LinkerParams = {
    accept_incoming?: boolean;
    decorate_forms?: boolean;
    domains: string[];
    url_position?: "query" | "fragment";
};

/**
 * Enable tracking
 *
 * By default uses the provided tagId and all additional accounts in the plugin configuration.
 * If a tagId is provided, it will only enable that account.
 */
export declare function optIn(tagId?: TagId): void;

/**
 * Disable tracking

 * By default uses the provided tagId and all additional accounts in the plugin configuration.
 * If a tagId is provided, it will only disable that account.
 */
export declare function optOut(tagId?: TagId): void;

declare type PageTracker = {
    /**
     * Vue Router instance used for tracking navigation events.
     */
    router: Router;
    /**
     * Custom template for generating route tracking events.
     */
    template?: PageTrackerTemplate;
    /**
     * Use `screen_view` instead of the default `page_view` event.
     * @default false
     */
    useScreenview?: boolean;
    /**
     * Defines routes to exclude from tracking.
     * - Can be an array of route objects identified by `path` or `name`.
     * - Can also be a function that returns `true` to exclude the route from tracking.
     */
    exclude?: PageTrackerExclude;
    /**
     * Set `send_page_view` for each route change.
     * @default true
     */
    sendPageView?: boolean;
    /**
     * Use the router base path option
     */
    useRouterBasePath?: boolean;
    /**
     * Sets the `page_path` equal to the route `fullPath` instead of `path` property
     */
    useRouteFullPath?: boolean;
};

declare type PageTrackerExclude = Array<{
    path?: string;
    name?: string;
}> | ((route: Route) => boolean);

declare type PageTrackerParams = Pageview | Screenview;

declare type PageTrackerTemplate = PageTrackerParams | ((route: Route) => PageTrackerParams);

export declare type Pageview = GtagConfigParams;

export declare function pageview(params: PageviewParams): void;

export declare type PageviewParams = string | Route | Pageview;

declare type PluginSettings = Partial<Settings> & Required<Pick<Settings, "tagId">>;

export declare function query(...args: QueryParams): void;

export declare type QueryParams = Parameters<Gtag>;

declare type Resource = {
    /**
     * URL of the gtag.js script.
     * @default "https://www.googletagmanager.com/gtag/js"
     */
    url?: string;
    /**
     * Enable preconnecting to the script's domain for faster loading.
     * @default false
     */
    preconnect?: boolean;
    /**
     * Load the script with the `defer` attribute.
     * @default false
     */
    defer?: boolean;
    /**
     * A nonce value for the script tag, useful for enforcing Content Security Policy (CSP).
     */
    nonce?: string;
    /**
     * Download gtag.js script
     * @default true
     */
    inject?: boolean;
};

declare type Route = RouteLocationNormalizedGeneric;

declare type Router = Router_2;

export declare type Screenview = {
    app_name?: string;
    screen_name?: string;
};

export declare function screenview(params: ScreenviewParams): void;

export declare type ScreenviewParams = string | Route | Screenview;

export declare function set(...args: SetParams): void;

declare type SetParams = GtagCommands["set"];

declare type Settings = {
    /**
     * Primary Google Tag Manager or Google Analytics tag ID.
     */
    tagId?: TagId;
    /**
     * Configuration settings for the main `tagId`.
     */
    config?: GtagConfig;
    /**
     * Additional tag IDs and their configurations to be tracked alongside the main `tagId`.
     */
    additionalAccounts?: Array<{
        tagId: TagId;
        config?: GtagConfig;
    }>;
    /**
     * Configuration for loading the gtag.js script.
     */
    resource: Resource;
    /**
     * Custom global variable name for the data layer.
     * @default "dataLayer"
     */
    dataLayerName: string;
    /**
     * Custom global function name for `gtag`.
     * @default "gtag"
     */
    gtagName: string;
    /**
     * Settings for automatic route tracking.
     * Make sure to disable pageview tracking from the "Enhanced measurement" in your Data Stream to avoid
     * possible double-tracking of your routes.
     */
    pageTracker?: PageTracker;
    /**
     * Configuration for cross-domain tracking.
     */
    linker?: LinkerParams;
    /**
     * Custom analytics group name.
     * @default "default"
     */
    groupName: string;
    /**
     * Collection of lifecycle hooks and event callbacks for tracking and configuration.
     */
    hooks?: Hooks;
    /**
     * Default consent mode applied during initialization.
     */
    consentMode?: "denied" | "granted";
    /**
     * Whether to initialize the Google tag script immediately after the page has loaded.
     *
     * @remarks
     * - Set this to `manual` to delay the initialization until you call the `addGtag` function manually.
     * - Set this to `manual` if you want to use the `useConsent` composable.
     *
     * @default 'auto'
     */
    initMode?: "auto" | "manual";
    /**
     * Default value for `app_name` when using the `screen_view` tracking method.
     */
    appName?: string;
};

declare type TagId = string;

export declare function time(params: GtagEventParams): void;

/**
 * Provides functionality to manage user consent.
 * @remark Make sure to set `initMode` to `manual`
 */
export declare function useConsent(): UseWithConsentReturn;

export declare type UseWithConsentReturn = {
    hasConsent: Ref<boolean>;
    acceptAll: () => void;
    rejectAll: () => void;
    acceptCustom: (params: GtagConsentParams) => void;
};

export { }


declare global {
    interface Window {
        [key: string]: any | any[];
    }
}


declare module "vue" {
    interface ComponentCustomProperties {
        $gtag: GtagAPI;
    }
}
