import { TemplateRef } from '@angular/core';
import { PassThrough, PassThroughOption, ScrollerOptions } from 'primeng/api';

/**
 * Defines valid pass-through options in ListBox component.
 * @template I Type of instance.
 *
 * @see {@link Listbox.pt}
 * @group Interface
 */
interface ListBoxPassThroughOptions<I = unknown> {
    /**
     * Used to pass attributes to the root's DOM element.
     */
    root?: PassThroughOption<HTMLDivElement, I>;
    /**
     * Used to pass attributes to the header's DOM element.
     */
    header?: PassThroughOption<HTMLDivElement, I>;
    /**
     * Used to pass attributes to the Checkbox component.
     */
    pcCheckbox?: any;
    /**
     * Used to pass attributes to the IconField component.
     */
    pcFilterContainer?: any;
    /**
     * Used to pass attributes to the filter input's DOM element.
     */
    pcFilter?: any;
    /**
     * Used to pass attributes to the InputIcon component.
     */
    pcFilterIconContainer?: any;
    /**
     * Used to pass attributes to the filter icon's DOM element.
     */
    filterIcon?: PassThroughOption<SVGElement, I>;
    /**
     * Used to pass attributes to the hidden filter result's DOM element.
     */
    hiddenFilterResult?: PassThroughOption<HTMLSpanElement, I>;
    /**
     * Used to pass attributes to the list container's DOM element.
     */
    listContainer?: PassThroughOption<HTMLDivElement, I>;
    /**
     * Used to pass attributes to the VirtualScroller component.
     */
    virtualScroller?: any;
    /**
     * Used to pass attributes to the list's DOM element.
     */
    list?: PassThroughOption<HTMLUListElement, I>;
    /**
     * Used to pass attributes to the option group's DOM element.
     */
    optionGroup?: PassThroughOption<HTMLLIElement, I, ListBoxContext>;
    /**
     * Used to pass attributes to the option's DOM element.
     */
    option?: PassThroughOption<HTMLLIElement, I, ListBoxContext>;
    /**
     * Used to pass attributes to the option check icon's DOM element.
     */
    optionCheckIcon?: PassThroughOption<SVGElement, I>;
    /**
     * Used to pass attributes to the option blank icon's DOM element.
     */
    optionBlankIcon?: PassThroughOption<SVGElement, I>;
    /**
     * Used to pass attributes to the empty message's DOM element.
     */
    emptyMessage?: PassThroughOption<HTMLLIElement, I>;
    /**
     * Used to pass attributes to the hidden empty message's DOM element.
     */
    hiddenEmptyMessage?: PassThroughOption<HTMLSpanElement, I>;
    /**
     * Used to pass attributes to the hidden selected message's DOM element.
     */
    hiddenSelectedMessage?: PassThroughOption<HTMLSpanElement, I>;
    /**
     * Used to pass attributes to the first hidden focusable element.
     */
    hiddenFirstFocusableEl?: PassThroughOption<HTMLSpanElement, I>;
    /**
     * Used to pass attributes to the last hidden focusable element.
     */
    hiddenLastFocusableEl?: PassThroughOption<HTMLSpanElement, I>;
}
/**
 * Defines valid pass-through options in ListBox component.
 * @see {@link ListBoxPassThroughOptions}
 *
 * @template I Type of instance.
 */
type ListBoxPassThrough<I = unknown> = PassThrough<I, ListBoxPassThroughOptions<I>>;
/**
 * Filter options of listbox.
 * @group Interface
 */
interface ListboxFilterOptions {
    /**
     * Callback to filter options.
     * @param {any} value - Filter value.
     */
    filter?: (value?: any) => void;
    /**
     * Callback to reset filter.
     */
    reset?: () => void;
}
/**
 * Custom change event.
 * @group Events
 */
interface ListboxChangeEvent {
    /**
     * Original event
     */
    originalEvent: Event;
    /**
     * Selected option value
     */
    value: any;
}
/**
 * Custom change event.
 * @group Events
 */
interface ListboxSelectAllChangeEvent {
    /**
     * Browser event.
     */
    originalEvent: Event;
    /**
     * Boolean value indicates whether all data is selected.
     */
    checked: boolean;
}
/**
 * Custom filter event.
 * @group Events
 */
interface ListboxFilterEvent {
    /**
     * Browser event.
     */
    originalEvent: Event;
    /**
     * Filter value.
     */
    filter: any;
}
/**
 * Custom change event.
 * @group Events
 */
interface ListboxClickEvent {
    /**
     * Browser event.
     */
    originalEvent: Event;
    /**
     * Value of the component.
     */
    value: any;
    /**
     * Selected option
     */
    option?: any;
}
/**
 * Custom change event.
 * @group Events
 */
interface ListboxDoubleClickEvent extends ListboxClickEvent {
}
/**
 * Custom item template context.
 * @group Interface
 */
interface ListboxItemTemplateContext<T = any> {
    /**
     * Data of the option.
     */
    $implicit: T;
    /**
     * Index of the option.
     */
    index: number;
    /**
     * Whether the option is selected.
     */
    selected: boolean;
    /**
     * Whether the option is disabled.
     */
    disabled: boolean;
}
/**
 * Custom group template context.
 * @group Interface
 */
interface ListboxGroupTemplateContext<T = any> {
    /**
     * Group option data.
     */
    $implicit: T;
}
/**
 * Custom header template context.
 * @group Interface
 */
interface ListboxHeaderTemplateContext<T = any> {
    /**
     * Current model value.
     */
    $implicit: T;
    /**
     * Visible options.
     */
    options: any[];
}
/**
 * Custom filter template context.
 * @group Interface
 */
interface ListboxFilterTemplateContext {
    /**
     * Filter options.
     */
    options: ListboxFilterOptions;
}
/**
 * Custom footer template context.
 * @group Interface
 */
interface ListboxFooterTemplateContext<T = any> {
    /**
     * Current model value.
     */
    $implicit: T;
    /**
     * Visible options.
     */
    options: any[];
}
/**
 * Custom check icon template context.
 * @group Interface
 */
interface ListboxCheckIconTemplateContext {
    /**
     * Whether the item is selected.
     */
    $implicit: boolean;
}
/**
 * Custom checkmark template context.
 * Note: Uses 'implicit' property instead of '$implicit'.
 * @group Interface
 */
interface ListboxCheckmarkTemplateContext {
    /**
     * Whether the item is selected.
     */
    implicit: boolean;
}
/**
 * Custom loader template context.
 * @group Interface
 */
interface ListboxLoaderTemplateContext {
    /**
     * Scroller options.
     */
    options: ScrollerOptions;
}
/**
 * Defines valid templates in Listbox.
 * @group Templates
 */
interface ListboxTemplates {
    /**
     * Custom item template.
     * @param {Object} context - item data.
     */
    item(context: ListboxItemTemplateContext): TemplateRef<ListboxItemTemplateContext>;
    /**
     * Custom group template.
     * @param {Object} context - group data.
     */
    group(context: ListboxGroupTemplateContext): TemplateRef<ListboxGroupTemplateContext>;
    /**
     * Custom header template.
     * @param {Object} context - header context.
     */
    header(context: ListboxHeaderTemplateContext): TemplateRef<ListboxHeaderTemplateContext>;
    /**
     * Custom filter template.
     * @param {Object} context - filter options.
     */
    filter(context: ListboxFilterTemplateContext): TemplateRef<ListboxFilterTemplateContext>;
    /**
     * Custom footer template.
     * @param {Object} context - footer context.
     */
    footer(context: ListboxFooterTemplateContext): TemplateRef<ListboxFooterTemplateContext>;
    /**
     * Custom empty template.
     */
    empty(): TemplateRef<void>;
    /**
     * Custom empty filter template.
     */
    emptyfilter(): TemplateRef<void>;
    /**
     * Custom filter icon template.
     */
    filtericon(): TemplateRef<void>;
    /**
     * Custom check icon template.
     * @param {Object} context - check icon context.
     */
    checkicon(context: ListboxCheckIconTemplateContext): TemplateRef<ListboxCheckIconTemplateContext>;
    /**
     * Custom checkmark template.
     * @param {Object} context - checkmark context.
     */
    checkmark(context: ListboxCheckmarkTemplateContext): TemplateRef<ListboxCheckmarkTemplateContext>;
    /**
     * Custom loader template for virtual scroll.
     * @param {Object} context - loader context.
     */
    loader(context: ListboxLoaderTemplateContext): TemplateRef<ListboxLoaderTemplateContext>;
}
/**
 * Defines context options for ListBox passthrough.
 * @group Interface
 */
interface ListBoxContext {
    /**
     * Whether the option is selected.
     */
    selected?: boolean;
    /**
     * Whether the option is focused.
     */
    focused?: boolean;
    /**
     * Whether the option is disabled.
     */
    disabled?: boolean;
}

export type { ListBoxContext, ListBoxPassThrough, ListBoxPassThroughOptions, ListboxChangeEvent, ListboxCheckIconTemplateContext, ListboxCheckmarkTemplateContext, ListboxClickEvent, ListboxDoubleClickEvent, ListboxFilterEvent, ListboxFilterOptions, ListboxFilterTemplateContext, ListboxFooterTemplateContext, ListboxGroupTemplateContext, ListboxHeaderTemplateContext, ListboxItemTemplateContext, ListboxLoaderTemplateContext, ListboxSelectAllChangeEvent, ListboxTemplates };
