import { EventEmitter, OnDestroy, Type } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import { DialogService, DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
import { ButtonDialogButtonDetails, ButtonDialogCustomButtonDetails } from '../model/button-dialog';
import { PrimeIcon, TranslationKey } from '@onecx/angular-accelerator';
import { Router } from '@angular/router';
import { EventsTopic } from '@onecx/integration-interface';
import { ShellCapabilityService } from '@onecx/angular-integration-interface';
import { AppStateService } from '@onecx/angular-integration-interface';
import * as i0 from "@angular/core";
/**
 * Object containing message of type {@link TranslationKey} and icon to be displayed along the message.
 *
 * @example
 * DialogMessage with TranslationKey will display 'text with parameter value = hello' and question mark icon
 *
 * ## Assume such translation is in the translation file
 * ```
 * const translations = {
 *   MY_KEY = 'text with parameter value = {{value}}',
 * }
 * ```
 *
 * ## DialogMessage declaration
 * ```
 * const myDialogMessage: DialogMessage = {
 *   message: {
 *     key: 'MY_KEY',
 *     parameters: {
 *       value = 'hello',
 *     },
 *   },
 *   icon: PrimeIcons.QUESTION
 * }
 * ```
 */
type DialogMessage = {
    message: TranslationKey;
    icon: PrimeIcon;
};
/**
 * Implement via component class to be displayed by {@link PortalDialogService.openDialog}
 *
 * Use if you want {@link PortalDialogService.openDialog} to return state of displayed component's current dialogResult value alongside the clicked button.
 *
 * @example
 * Display component implementing DialogResult<string> and react on the returned value
 *
 * ## Component declaration
 * ```
 * ⁣@Component({template: `<div>
 * <input (change)="onInputChange($event)">
 * </div>`})
 * export class MyInputComponent implements DialogResult<string> {
 *   dialogResult: string = ''
 *
 *   onInputChange(event: any) {
 *     this.dialogResult = event.target.value
 *   }
 * }
 * ```
 *
 * ## PortalDialogService call
 * ```
 * portalDialogService.openDialog(title, { type: MyInputComponent }, primaryButton, ...).subscribe((result: DialogState<string>) => {
 * // result.value === MyInputComponent.dialogResult (during button click)
 * // behavior when dialog closes
 * })
 * ```
 *
 */
export interface DialogResult<T> {
    dialogResult: T;
}
/**
 * Implement via component class to be displayed by {@link PortalDialogService.openDialog}
 *
 * Use to control the state of the primary button (disabled or enabled). Whenever your component wants to disable/enable primary button it should emit boolean equal to whether primary button should be enabled.
 *
 * If you implement this interface then primary button will be disabled until the emitter emits true
 */
export interface DialogPrimaryButtonDisabled {
    primaryButtonEnabled: EventEmitter<boolean>;
}
/**
 * Implement via component class to be displayed by {@link PortalDialogService.openDialog}
 *
 * Use to control the state of the secondary button (disabled or enabled). Whenever your component wants to disable/enable secondary button it should emit boolean equal to whether secondary button should be enabled.
 *
 * If you implement this interface then secondary button will be disabled until the emitter emits true
 */
export interface DialogSecondaryButtonDisabled {
    secondaryButtonEnabled: EventEmitter<boolean>;
}
/**
 * Implement via component class to be displayed by {@link PortalDialogService.openDialog}
 *
 * Use to control the state of custom buttons (disabled or enabled). Whenever your component wants to disable/enable any custom button it should emit an object indicating which button should be disabled/enabled. This object should contain id property (string) related to previously defined button and enabled property (boolean) equal to whether custom button should be enabled.
 *
 * If you implement this interface then all custom buttons will be disabled until the emitter emits true
 */
export interface DialogCustomButtonsDisabled {
    customButtonEnabled: EventEmitter<{
        id: string;
        enabled: boolean;
    }>;
}
/**
 * Implement via component class to be displayed by {@link PortalDialogService.openDialog}
 *
 * Use to add behavior on button clicks. {@link DialogButtonClicked.ocxDialogButtonClicked} method will be called everytime any button is clicked and should return boolean value (or Observable<boolean> or Promise<boolean>) equal to whether dialog should be closed or not.
 *
 * {@link DialogButtonClicked.ocxDialogButtonClicked} will recieve object containing component's state captured on button click. It will have button property with value 'primary' or 'secondary' which determines which button was clicked.
 *
 * It will also have result property which by default will be undefined, however if you want to add any properties to the state please combine this interface with {@link DialogResult}. That way result will be equal to component's dialogResult property captured on button click.
 *
 * @example
 * Display component implementing DialogResult<string> and DialogButtonClicked which should not close dialog on clear click but should close when send clicked and api call was sucessful
 *
 * ## Component declaration
 * ```
 * ⁣@Component({template: `<div>
 * <input (change)="onInputChange($event)">
 * </div>`})
 * export class MyInputComponent implements DialogResult<string>, DialogButtonClicked {
 *   dialogResult: string = ''
 *
 *   onInputChange(event: any) {
 *     this.dialogResult = event.target.value
 *   }
 *
 *   ocxDialogButtonClicked(state: DialogState<string>) {
 *     // here you can do any operations you desire
 *     // such as form validation
 *     // api calls and so on
 *     if (state.button === 'primary') {
 *       // send form data to server
 *       this.apiService.postInput(state.result, ...).pipe(
 *         // map response to boolean meaning if call was successfull
 *       )
 *       return true // if dialog should be closed return true
 *     } else {
 *       // clear input
 *       return false // don't want to close the dialog, only to clear it
 *     }
 *   }
 * }
 * ```
 *
 * ## PortalDialogService call
 * ```
 * portalDialogService.openDialog(title, { type: MyInputComponent }, "Send", "Clear").subscribe((result: DialogState<string>) => {
 * // behavior to be fired when dialog closes
 * })
 * ```
 */
export interface DialogButtonClicked<T = unknown> {
    ocxDialogButtonClicked(state: DialogState<T>): Observable<boolean> | Promise<boolean> | boolean | undefined | void;
}
/**
 * Object containing component type to be displayed and inputs to populate the component.
 *
 * @example
 *
 * ```
 * ⁣@Component({template: `<h1>{{content}}</h1>`})
 * export class MyComponent {
 *   ⁣@Input() content: string = ''
 * }
 * const myComponent = {
 *   type: MyComponent,
 *   inputs: {
 *     content: 'My header content',
 *   },
 * }
 * ```
 */
type Component<T extends unknown> = unknown extends T ? {
    type: Type<any>;
    inputs?: Record<string, unknown>;
} : {
    type: Type<DialogResult<T>>;
    inputs?: Record<string, unknown>;
};
export type DialogButton = 'primary' | 'secondary' | 'custom';
export type DialogStateButtonClicked = 'primary' | 'secondary' | 'custom';
/**
 * Object containing information about clicked button ('primary' or 'secondary') and displayed component state captured on button click (only if component implements {@link DialogResult} interface)
 */
export type DialogState<T> = {
    button: DialogStateButtonClicked;
    result: T | undefined;
    id?: string;
};
export type PortalDialogConfig = {
    showXButton?: boolean;
    customButtons?: ButtonDialogCustomButtonDetails[];
    autoFocusButton?: DialogButton;
    autoFocusButtonCustomId?: string;
    ariaLabelledBy?: string;
    width?: string;
    height?: string;
    closeOnEscape?: boolean;
    focusOnShow?: boolean;
    focusTrap?: boolean;
    baseZIndex?: number;
    autoZIndex?: boolean;
    dismissableMask?: boolean;
    showHeader?: boolean;
    modal?: boolean;
    resizable?: boolean;
    draggable?: boolean;
    keepInViewport?: boolean;
    minX?: number;
    minY?: number;
    maximizable?: boolean;
    maximizeIcon?: string;
    minimizeIcon?: string;
    position?: string;
    closeAriaLabel?: string;
};
export interface PortalDialogServiceData {
    primaryButtonEnabled$: EventEmitter<boolean>;
    secondaryButtonEnabled$: EventEmitter<boolean>;
    customButtonEnabled$: EventEmitter<{
        id: string;
        enabled: boolean;
    }>;
    buttonClicked$: EventEmitter<DialogState<unknown>>;
}
export declare class PortalDialogService implements OnDestroy {
    private dialogService;
    private translateService;
    private capabilityService;
    private appStateService;
    private router;
    private _eventsTopic$;
    get eventsTopic(): EventsTopic;
    set eventsTopic(value: EventsTopic);
    constructor(dialogService: DialogService, translateService: TranslateService, capabilityService: ShellCapabilityService, appStateService: AppStateService, router: Router);
    ngOnDestroy(): void;
    /**
     * @deprecated
     */
    open(componentType: Type<any>, config: DynamicDialogConfig): DynamicDialogRef;
    /**
     * Opens dialog with a component or message to display and one or two buttons. This method allows you to customize the dialog using parameters and by implementic specific interfaces via component to be displayed. The dialog is only shown if if you subscribe to this function.
     *
     * Displaying component inisde the dialog can be achieved by providing the component class with optional inputs. By default the component will be shown without any interaction with the dialog, however you can implement the following interfaces by your component class to allow for some interactions:
     * - {@link DialogResult} - dialog state will contain dialogResult property
     *
     * - {@link DialogButtonClicked} - on button click ocxDialogButtonClicked function will be called with dialog state as a parameter. You should return true if you want dialog to be close or false if not and add any operations on your component.
     *
     * - {@link DialogPrimaryButtonDisabled} - dialog will use the EventEmitter to determine if the primary button should be disabled
     *
     * - {@link DialogSecondaryButtonDisabled} - dialog will use the EventEmitter to determine if the secondary button should be disabled
     *
     * - {@link DialogCustomButtonsDisabled} - dialog will use the EventEmitter to determine if the custom buttons should be disabled
     *
     * @param title Translation key for dialog title
     * @param componentOrMessage Either a component or a translation key of a message with optional parameters and icon to be displayed next to the message
     * @param primaryButtonTranslationKeyOrDetails Translation key with optional parameters and icon to be displayed next to the text of the button
     * @param secondaryButtonTranslationKeyOrDetails Translation key with optional parameters and icon to be displayed next to the text of the button
     * @param extras Configuration object allowing for customization of the dialog behavior and visual aspects
     * @returns Observable containing dialog state on close
     *
     *
     * @example
     * Display dialog with message and two buttons using translation keys
     *
     * ```
     * // assume 'TITLE_KEY', 'WELCOME_MESSAGE', 'OK_BUTTON' and 'REFRESH_BUTTON' are translation keys
     * this.portalDialogService.openDialog('TITLE_KEY', 'WELCOME_MESSAGE', 'OK_BUTTON', 'REFRESH_BUTTON').subscribe((stateOnClose) => {
     *   // operations when dialog has been closed
     * })
     * ```
     *
     * @example
     * Display dialog message with icon and single button
     *
     * ```
     * // Welcome message with question mark icon
     * const dialogMessage = {
     *   key: 'WELCOME_MESSAGE',
     *   icon: PrimeIcons.QUESTION
     * }
     * this.portalDialogService.openDialog('TITLE_KEY', dialogMessage, 'OK_BUTTON').subscribe((stateOnClose) => {
     *   // operations when dialog has been closed
     * })
     * ```
     *
     * @example
     * Display dialog message with two customized buttons
     *
     * ```
     * // Ok button with check icon
     * const primaryButton = {
     *   key: 'OK_BUTTON',
     *   icon: PrimeIcons.CHECK
     *   tooltipKey: 'OK_TOOLTIP',
     *   tooltipPosition: 'bottom'
     * }
     *
     * // Refresh button with refresh icon
     * const secondaryButton = {
     *   key: 'REFRESH_BUTTON',
     *   icon: PrimeIcons.REFRESH
     *   tooltipKey: 'REFRESH_TOOLTIP',
     *   tooltipPosition: 'right'
     * }
     *
     * this.portalDialogService.openDialog('TITLE_KEY', 'WELCOME_MESSAGE', primaryButton, secondaryButton).subscribe((stateOnClose) => {
     *   // operations when dialog has been closed
     * })
     * ```
     *
     * @example
     * Display dialog message without X button in top right corner
     *
     * ```
     * this.portalDialogService.openDialog('TITLE_KEY', 'WELCOME_MESSAGE', 'OK_BUTTON', 'REFRESH_BUTTON', false).subscribe((stateOnClose) => {
     *   // operations when dialog has been closed
     * })
     * ```
     *
     * @example
     * React on dialog closing
     *
     * ```
     * this.portalDialogService.openDialog('TITLE_KEY', 'WELCOME_MESSAGE', 'OK_BUTTON', 'REFRESH_BUTTON').subscribe((stateOnClose) => {
     *   // operations when dialog has been closed
     * })
     * ```
     *
     * @example
     * Display dialog with component
     *
     * ## Component declaration
     * ```
     * ⁣@Component({template: `<div>
     * <h1>{{header | translate}}</h1>
     * <input (change)="onInputChange($event)">
     * </div>`})
     * export class MyInputComponent implements DialogResult<string>,  DialogButtonClicked, DialogPrimaryButtonDisabled, DialogSecondaryButtonDisabled {
     *   ⁣@Input() header: string = ''
     *   // change value to manipulate component state visible by dialog
     *   dialogResult: string = ''
     *   // emit true/false to disable primary button
     *   ⁣@Output() primaryButtonEnabled: EventEmitter<boolean> = new EventEmitter()
     *   // emit true/false to disable secondary button
     *   ⁣@Output() secondaryButtonEnabled: EventEmitter<boolean> = new EventEmitter()
     *
     *   // implement operations to be done on button clicks and return if the dialog should be closed
     *   ocxDialogButtonClicked(state: DialogState<string>) {
     *     return true
     *   }
     *
     *   onInputChange(event: any) {
     *     this.dialogResult = event.target.value
     *   }
     * }
     * ```
     *
     * ## PortalDialogService call
     * ```
     * const myComponent = {
     *   type: MyInputComponent,
     *   inputs: {
     *     header: 'DIALOG_HEADER'
     *   }
     * }
     * this.portalDialogService.openDialog('TITLE_KEY', myComponent, 'OK_BUTTON', 'REFRESH_BUTTON').subscribe((stateOnClose) => {
     *   // operations when dialog has been closed
     * })
     * ```
     *
     * @example
     * Display dialog with component without passing inputs
     *
     * ## PortalDialogService call
     * ```
     * this.portalDialogService.openDialog('TITLE_KEY', MyInputComponent, 'OK_BUTTON', 'REFRESH_BUTTON').subscribe((stateOnClose) => {
     *   // operations when dialog has been closed
     * })
     * ```
     */
    openDialog<T>(title: TranslationKey | null, componentOrMessage: Type<any> | Type<DialogResult<T>> | Component<T> | TranslationKey | DialogMessage, primaryButtonTranslationKeyOrDetails: TranslationKey | ButtonDialogButtonDetails, secondaryButtonTranslationKeyOrDetails?: TranslationKey | ButtonDialogButtonDetails, extras?: PortalDialogConfig): Observable<DialogState<T>>;
    /**
     * @deprecated Use `extras` instead of `showXButton`
     */
    openDialog<T>(title: TranslationKey | null, componentOrMessage: Type<any> | Type<DialogResult<T>> | Component<T> | TranslationKey | DialogMessage, primaryButtonTranslationKeyOrDetails: TranslationKey | ButtonDialogButtonDetails, secondaryButtonTranslationKeyOrDetails?: TranslationKey | ButtonDialogButtonDetails, showXButton?: boolean): Observable<DialogState<T>>;
    private cleanupAndCloseDialog;
    private removeDialogFromHtml;
    private findBodyChild;
    private prepareTitleForTranslation;
    private buttonDetailsOrTranslationKey;
    private getComponentToRender;
    private isTranslationKey;
    private isString;
    private isDialogMessage;
    private isType;
    static ɵfac: i0.ɵɵFactoryDeclaration<PortalDialogService, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<PortalDialogService>;
}
export declare function providePortalDialogService(): (typeof DialogService | typeof PortalDialogService)[];
export {};
