import * as _shival99_angular_virtual from '@shival99/angular-virtual';
import * as _angular_core from '@angular/core';
import { TemplateRef, Signal, OnInit, ElementRef, PipeTransform } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
import { ZIcon } from '@shival99/z-ui/components/z-icon';
import { ZPopoverPosition, ZPopoverControl } from '@shival99/z-ui/components/z-popover';
import { ZAsyncOptionsConfig, ZEvent } from '@shival99/z-ui/utils';
import { ClassValue } from 'clsx';
import { Observable } from 'rxjs';
import * as class_variance_authority_types from 'class-variance-authority/types';

declare class ZSelectOptionDirective<T = unknown> {
    readonly templateRef: TemplateRef<any>;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ZSelectOptionDirective<any>, never>;
    static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ZSelectOptionDirective<any>, "[z-select-option], [zSelectOption]", never, {}, {}, never, never, true, never>;
}

declare class ZSelectSelectedDirective<T = unknown> {
    readonly templateRef: TemplateRef<any>;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ZSelectSelectedDirective<any>, never>;
    static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ZSelectSelectedDirective<any>, "[z-select-selected], [zSelectSelected]", never, {}, {}, never, never, true, never>;
}

interface ZSelectControl<T = unknown> {
    /** Trigger validation and return true if valid */
    valid: () => boolean;
    /**
     * Trigger validation and return true if has error.
     * @deprecated Use `valid()` for boolean form-submit checks.
     */
    validate: () => boolean;
    /** Reset component to initial state */
    reset: () => void;
    /** Focus the select trigger */
    focus: () => void;
    /** Blur the select trigger */
    blur: () => void;
    /** Set custom error message (useful for server-side validation). Pass null to clear. */
    setErrorMessage: (message: string | null) => void;
    /** Signal indicating if component has validation error */
    hasError: Signal<boolean>;
    /** Signal indicating if async validation is in progress */
    isValidating: Signal<boolean>;
    /** Signal indicating if dropdown is open */
    isOpen: Signal<boolean>;
    /** Signal with current value */
    value: Signal<T | T[] | null>;
    /** Signal with currently selected option (single mode) */
    selectedOption: Signal<ZSelectOption<T> | null>;
    /** Signal with all selected options (multiple/tags mode) */
    selectedOptions: Signal<ZSelectOption<T>[]>;
    /** Signal with current error message */
    errorMessage: Signal<string>;
}
type ZSelectMode = 'single' | 'multiple' | 'tags';
type ZSelectSize = 'sm' | 'default' | 'lg';
type ZSelectAsyncValidateOn = 'change' | 'blur';
interface ZSelectOption<T = unknown> {
    label: string;
    value: T;
    disabled?: boolean;
    group?: string;
    icon?: string;
}
interface ZSelectConfig<T = unknown> {
    /** Số ký tự tối thiểu trước khi gọi async.load khi người dùng search. */
    minLength: number;
    /** Debounce search tính bằng mili giây, ưu tiên hơn zDebounce khi được truyền trong zConfig. */
    debounceTime: number;
    /** Config để component tự search, load-more, loading và append options. */
    async?: ZAsyncOptionsConfig<ZSelectOption<T>>;
}
declare const Z_SELECT_DEFAULT_CONFIG: Omit<ZSelectConfig, 'async'>;
interface ZSelectAsyncValidator<T = unknown> {
    error: string;
    message: string;
    validate: (value: ZSelectOption<T> | ZSelectOption<T>[] | null) => Promise<boolean> | Observable<boolean>;
}
interface ZSelectValidator<T = unknown> {
    error: string;
    message: string;
    validate: (value: ZSelectOption<T> | ZSelectOption<T>[] | null) => boolean;
}
interface ZSelectOptionGroup<T = unknown> {
    label: string;
    options: ZSelectOption<T>[];
}
interface ZSelectLoadMoreEvent {
    currentCount: number;
    scrollTop: number;
}
type ZSelectLabelTemplate<T = unknown> = TemplateRef<{
    $implicit: ZSelectOption<T>;
}>;
type ZSelectOptionTemplate<T = unknown> = TemplateRef<{
    $implicit: ZSelectOption<T>;
    selected: boolean;
}>;
interface ZSelectTagColor {
    bg: string;
    text: string;
    border: string;
}
declare const TAG_COLORS: ZSelectTagColor[];

declare class ZSelectComponent<T = unknown> implements OnInit, ControlValueAccessor {
    private readonly _injector;
    private readonly _destroyRef;
    private readonly _zTranslate;
    protected readonly triggerRef: _angular_core.Signal<ElementRef<HTMLDivElement> | undefined>;
    protected readonly searchInputRef: _angular_core.Signal<ElementRef<HTMLInputElement> | undefined>;
    protected readonly dropdownTpl: _angular_core.Signal<TemplateRef<unknown> | undefined>;
    protected readonly optionsContainerRef: _angular_core.Signal<ElementRef<HTMLDivElement> | undefined>;
    protected readonly virtualScrollRef: _angular_core.Signal<ElementRef<HTMLDivElement> | undefined>;
    protected readonly loadMoreSentinelRef: _angular_core.Signal<ElementRef<HTMLDivElement> | undefined>;
    protected readonly customSelectedDirective: _angular_core.Signal<ZSelectSelectedDirective<any> | undefined>;
    protected readonly customOptionDirective: _angular_core.Signal<ZSelectOptionDirective<any> | undefined>;
    readonly zOnSearch: _angular_core.OutputEmitterRef<string>;
    readonly zOnLoadMore: _angular_core.OutputEmitterRef<ZSelectLoadMoreEvent>;
    readonly zOnBlur: _angular_core.OutputEmitterRef<FocusEvent>;
    readonly zOnFocus: _angular_core.OutputEmitterRef<FocusEvent>;
    readonly zControl: _angular_core.OutputEmitterRef<ZSelectControl<T>>;
    readonly zEvent: _angular_core.OutputEmitterRef<ZEvent>;
    readonly class: _angular_core.InputSignal<ClassValue>;
    readonly zMode: _angular_core.InputSignal<ZSelectMode>;
    readonly zSize: _angular_core.InputSignal<ZSelectSize>;
    readonly zLabel: _angular_core.InputSignal<string>;
    readonly zLabelClass: _angular_core.InputSignal<string>;
    readonly zPlaceholder: _angular_core.InputSignal<string>;
    readonly zRequired: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zDisabled: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zReadonly: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zLoading: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zPrefix: _angular_core.InputSignal<"" | ZIcon>;
    readonly zAllowClear: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zWrap: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zShowSearch: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zPlaceholderSearch: _angular_core.InputSignal<string>;
    readonly zDebounce: _angular_core.InputSignal<number>;
    readonly zNotFoundText: _angular_core.InputSignal<string>;
    readonly zEmptyText: _angular_core.InputSignal<string>;
    readonly zEmptyIcon: _angular_core.InputSignal<ZIcon>;
    readonly zMaxTagCount: _angular_core.InputSignal<number>;
    readonly zDropdownMaxHeight: _angular_core.InputSignal<number>;
    readonly zOptionHeight: _angular_core.InputSignal<number>;
    readonly zVirtualScroll: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zShowAction: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zOptions: _angular_core.InputSignal<ZSelectOption<T>[]>;
    readonly zConfig: _angular_core.InputSignal<Partial<ZSelectConfig<T>>>;
    readonly zTranslateLabels: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zKey: _angular_core.InputSignal<string>;
    readonly zSearchServer: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zLoadingMore: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zEnableLoadMore: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zScrollDistance: _angular_core.InputSignal<number>;
    readonly zMaxVisible: _angular_core.InputSignal<number | null>;
    readonly zScrollClose: _angular_core.InputSignalWithTransform<boolean, string | boolean>;
    readonly zPosition: _angular_core.InputSignal<ZPopoverPosition>;
    readonly zSelectedTemplate: _angular_core.InputSignal<ZSelectLabelTemplate<T> | null>;
    readonly zOptionTemplate: _angular_core.InputSignal<ZSelectOptionTemplate<T> | null>;
    readonly zActionTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
    readonly zAsyncValidators: _angular_core.InputSignal<ZSelectAsyncValidator<T>[]>;
    readonly zAsyncDebounce: _angular_core.InputSignal<number>;
    readonly zAsyncValidateOn: _angular_core.InputSignal<ZSelectAsyncValidateOn>;
    readonly zValidators: _angular_core.InputSignal<ZSelectValidator<T>[]>;
    private readonly _value;
    private readonly _disabled;
    private readonly _formControl;
    private readonly _formStateVersion;
    private readonly _popoverControl;
    private readonly _allKnownOptions;
    private readonly _asyncErrors;
    private readonly _customError;
    private readonly _asyncOptions;
    private readonly _asyncKeyword;
    private readonly _asyncPage;
    private readonly _asyncHasMore;
    private readonly _asyncLoading;
    private readonly _asyncLoadingMore;
    protected readonly uiState: _angular_core.WritableSignal<{
        isOpen: boolean;
        hasScrollShadow: boolean;
        isFocused: boolean;
        isValidating: boolean;
        touched: boolean;
        dirty: boolean;
    }>;
    protected readonly selectId: string;
    protected readonly dropdownId: string;
    protected readonly searchText: _angular_core.WritableSignal<string>;
    protected readonly dropdownWidth: _angular_core.WritableSignal<number>;
    protected readonly currentValue: _angular_core.Signal<T | T[] | null>;
    protected readonly config: _angular_core.Signal<ZSelectConfig<T>>;
    protected readonly hasAsyncOptions: _angular_core.Signal<boolean>;
    protected readonly sourceOptions: _angular_core.Signal<ZSelectOption<T>[]>;
    protected readonly isLoading: _angular_core.Signal<boolean>;
    protected readonly isLoadingMore: _angular_core.Signal<boolean>;
    protected readonly canLoadMore: _angular_core.Signal<boolean>;
    protected readonly effectiveDebounceTime: _angular_core.Signal<number>;
    protected readonly virtualizer: _shival99_angular_virtual.AngularVirtualizer<HTMLDivElement, Element>;
    protected readonly isDisabled: _angular_core.Signal<boolean>;
    protected readonly isReadonly: _angular_core.Signal<boolean>;
    protected readonly isInteractionDisabled: _angular_core.Signal<boolean>;
    protected readonly effectivePlaceholder: _angular_core.Signal<string>;
    protected readonly effectivePlaceholderSearch: _angular_core.Signal<string>;
    protected readonly effectiveNotFoundText: _angular_core.Signal<string>;
    protected readonly effectiveEmptyText: _angular_core.Signal<string>;
    protected readonly effectiveSelectAllText: _angular_core.Signal<string>;
    protected readonly effectiveClearAllText: _angular_core.Signal<string>;
    protected readonly effectiveRequiredErrorText: _angular_core.Signal<string>;
    protected readonly translatedOptions: _angular_core.Signal<ZSelectOption<T>[]>;
    protected readonly isMultipleMode: _angular_core.Signal<boolean>;
    protected readonly isTagsMode: _angular_core.Signal<boolean>;
    protected readonly effectiveSelectedTemplate: _angular_core.Signal<TemplateRef<any> | null>;
    protected readonly effectiveOptionTemplate: _angular_core.Signal<TemplateRef<any> | null>;
    protected readonly knownOptions: _angular_core.Signal<ZSelectOption<T>[]>;
    protected readonly shouldUseVirtualScroll: _angular_core.Signal<boolean>;
    protected readonly selectedOption: _angular_core.Signal<ZSelectOption<T> | null>;
    protected readonly selectedOptions: _angular_core.Signal<ZSelectOption<T>[]>;
    protected readonly displayedTags: _angular_core.Signal<ZSelectOption<T>[]>;
    protected readonly remainingCount: _angular_core.Signal<number>;
    protected readonly hasValue: _angular_core.Signal<boolean>;
    protected readonly isAllSelected: _angular_core.Signal<boolean>;
    protected readonly filteredOptions: _angular_core.Signal<{
        label: string;
        value: T;
        disabled?: boolean;
    }[]>;
    protected readonly isEmptyData: _angular_core.Signal<boolean>;
    protected readonly isNoSearchResults: _angular_core.Signal<boolean>;
    protected readonly optionsMaxHeight: _angular_core.Signal<number>;
    protected readonly currentStatus: _angular_core.Signal<"default" | "disabled" | "readonly" | "open" | "error">;
    private readonly _shouldShowValidation;
    protected readonly hasError: _angular_core.Signal<boolean>;
    protected readonly errorMessage: _angular_core.Signal<string>;
    protected readonly selectClasses: _angular_core.Signal<string>;
    private readonly _searchSubject;
    private readonly _asyncCancelSubject;
    private readonly _asyncValidationSubject;
    private _loadMoreObserver;
    private _virtualScrollListener;
    private _asyncLoadSubscription;
    private _asyncRequestId;
    private _asyncValidationAbortController;
    private _onChange;
    private _onTouched;
    private _ngControl;
    private readonly _isNgModel;
    constructor();
    ngOnInit(): void;
    writeValue(value: T | T[] | null): void;
    registerOnChange(fn: (value: T | T[] | null) => void): void;
    registerOnTouched(fn: () => void): void;
    setDisabledState(isDisabled: boolean): void;
    reset(): void;
    focus(): void;
    blur(): void;
    /** @deprecated Use `valid()` for boolean form-submit checks. */
    validate(): boolean;
    valid(): boolean;
    setErrorMessage(message: string | null): void;
    protected onTriggerKeydown(event: KeyboardEvent): void;
    protected onTriggerMousedown(): void;
    protected toggleDropdown(): void;
    protected onPopoverControl(control: ZPopoverControl): void;
    protected onPopoverShow(): void;
    protected onPopoverHideStart(): void;
    protected onPopoverHideEnd(): void;
    protected onSearchChange(value: string): void;
    protected checkScrollShadow(): void;
    protected selectOption(option: ZSelectOption<T>, closeFn?: () => void): void;
    protected removeOption(event: MouseEvent, option: ZSelectOption<T>): void;
    protected clearAll(event: MouseEvent): void;
    protected selectAll(): void;
    protected removeAll(): void;
    protected toggleSelectAllAction(): void;
    protected trackByValue: (_index: number, option: ZSelectOption<T>) => unknown;
    private _emitControl;
    private _loadAsyncOptionsOnFocus;
    private _loadAsyncOptions;
    private _handleAsyncOptionsError;
    private _getAsyncOptionsScrollTop;
    private _restoreAsyncOptionsScrollTop;
    private _resetAsyncOptions;
    private _setupLoadMoreObserver;
    private _cleanupLoadMoreObserver;
    private _setupVirtualScrollLoadMore;
    private _cleanupVirtualScrollListener;
    private _handleLoadMore;
    private _getValidationErrors;
    private _runAsyncValidation;
    private _cancelAsyncValidation;
    private _triggerAsyncValidation;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ZSelectComponent<any>, never>;
    static ɵcmp: _angular_core.ɵɵComponentDeclaration<ZSelectComponent<any>, "z-select", ["zSelect"], { "class": { "alias": "class"; "required": false; "isSignal": true; }; "zMode": { "alias": "zMode"; "required": false; "isSignal": true; }; "zSize": { "alias": "zSize"; "required": false; "isSignal": true; }; "zLabel": { "alias": "zLabel"; "required": false; "isSignal": true; }; "zLabelClass": { "alias": "zLabelClass"; "required": false; "isSignal": true; }; "zPlaceholder": { "alias": "zPlaceholder"; "required": false; "isSignal": true; }; "zRequired": { "alias": "zRequired"; "required": false; "isSignal": true; }; "zDisabled": { "alias": "zDisabled"; "required": false; "isSignal": true; }; "zReadonly": { "alias": "zReadonly"; "required": false; "isSignal": true; }; "zLoading": { "alias": "zLoading"; "required": false; "isSignal": true; }; "zPrefix": { "alias": "zPrefix"; "required": false; "isSignal": true; }; "zAllowClear": { "alias": "zAllowClear"; "required": false; "isSignal": true; }; "zWrap": { "alias": "zWrap"; "required": false; "isSignal": true; }; "zShowSearch": { "alias": "zShowSearch"; "required": false; "isSignal": true; }; "zPlaceholderSearch": { "alias": "zPlaceholderSearch"; "required": false; "isSignal": true; }; "zDebounce": { "alias": "zDebounce"; "required": false; "isSignal": true; }; "zNotFoundText": { "alias": "zNotFoundText"; "required": false; "isSignal": true; }; "zEmptyText": { "alias": "zEmptyText"; "required": false; "isSignal": true; }; "zEmptyIcon": { "alias": "zEmptyIcon"; "required": false; "isSignal": true; }; "zMaxTagCount": { "alias": "zMaxTagCount"; "required": false; "isSignal": true; }; "zDropdownMaxHeight": { "alias": "zDropdownMaxHeight"; "required": false; "isSignal": true; }; "zOptionHeight": { "alias": "zOptionHeight"; "required": false; "isSignal": true; }; "zVirtualScroll": { "alias": "zVirtualScroll"; "required": false; "isSignal": true; }; "zShowAction": { "alias": "zShowAction"; "required": false; "isSignal": true; }; "zOptions": { "alias": "zOptions"; "required": false; "isSignal": true; }; "zConfig": { "alias": "zConfig"; "required": false; "isSignal": true; }; "zTranslateLabels": { "alias": "zTranslateLabels"; "required": false; "isSignal": true; }; "zKey": { "alias": "zKey"; "required": false; "isSignal": true; }; "zSearchServer": { "alias": "zSearchServer"; "required": false; "isSignal": true; }; "zLoadingMore": { "alias": "zLoadingMore"; "required": false; "isSignal": true; }; "zEnableLoadMore": { "alias": "zEnableLoadMore"; "required": false; "isSignal": true; }; "zScrollDistance": { "alias": "zScrollDistance"; "required": false; "isSignal": true; }; "zMaxVisible": { "alias": "zMaxVisible"; "required": false; "isSignal": true; }; "zScrollClose": { "alias": "zScrollClose"; "required": false; "isSignal": true; }; "zPosition": { "alias": "zPosition"; "required": false; "isSignal": true; }; "zSelectedTemplate": { "alias": "zSelectedTemplate"; "required": false; "isSignal": true; }; "zOptionTemplate": { "alias": "zOptionTemplate"; "required": false; "isSignal": true; }; "zActionTemplate": { "alias": "zActionTemplate"; "required": false; "isSignal": true; }; "zAsyncValidators": { "alias": "zAsyncValidators"; "required": false; "isSignal": true; }; "zAsyncDebounce": { "alias": "zAsyncDebounce"; "required": false; "isSignal": true; }; "zAsyncValidateOn": { "alias": "zAsyncValidateOn"; "required": false; "isSignal": true; }; "zValidators": { "alias": "zValidators"; "required": false; "isSignal": true; }; }, { "zOnSearch": "zOnSearch"; "zOnLoadMore": "zOnLoadMore"; "zOnBlur": "zOnBlur"; "zOnFocus": "zOnFocus"; "zControl": "zControl"; "zEvent": "zEvent"; }, ["customSelectedDirective", "customOptionDirective"], never, true, never>;
}

declare class ZIsSelectedPipe implements PipeTransform {
    transform<T>(option: ZSelectOption<T>, value: T | T[] | null, isMultipleMode: boolean): boolean;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ZIsSelectedPipe, never>;
    static ɵpipe: _angular_core.ɵɵPipeDeclaration<ZIsSelectedPipe, "zIsSelected", true>;
}

declare class ZOptionClassesPipe implements PipeTransform {
    transform(isSelected: boolean, isDisabled?: boolean): string;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ZOptionClassesPipe, never>;
    static ɵpipe: _angular_core.ɵɵPipeDeclaration<ZOptionClassesPipe, "zOptionClasses", true>;
}

declare class ZTagClassesPipe implements PipeTransform {
    transform<T>(option: ZSelectOption<T>, size: ZSelectSize, isTagsMode: boolean): string;
    static ɵfac: _angular_core.ɵɵFactoryDeclaration<ZTagClassesPipe, never>;
    static ɵpipe: _angular_core.ɵɵPipeDeclaration<ZTagClassesPipe, "zTagClasses", true>;
}

declare const zSelectVariants: (props?: ({
    zSize?: "sm" | "default" | "lg" | null | undefined;
    zStatus?: "default" | "open" | "error" | "disabled" | "readonly" | null | undefined;
} & class_variance_authority_types.ClassProp) | undefined) => string;
declare const zSelectTagVariants: (props?: ({
    zSize?: "sm" | "default" | "lg" | null | undefined;
} & class_variance_authority_types.ClassProp) | undefined) => string;
declare const zSelectOptionVariants: (props?: ({
    selected?: boolean | null | undefined;
    disabled?: boolean | null | undefined;
} & class_variance_authority_types.ClassProp) | undefined) => string;

declare function getTagColor(value: unknown): ZSelectTagColor;
declare function filterOptions<T>(options: {
    label: string;
    value: T;
    disabled?: boolean;
}[], searchText: string): {
    label: string;
    value: T;
    disabled?: boolean;
}[];

export { TAG_COLORS, ZIsSelectedPipe, ZOptionClassesPipe, ZSelectComponent, ZSelectOptionDirective, ZSelectSelectedDirective, ZTagClassesPipe, Z_SELECT_DEFAULT_CONFIG, filterOptions, getTagColor, zSelectOptionVariants, zSelectTagVariants, zSelectVariants };
export type { ZSelectAsyncValidateOn, ZSelectAsyncValidator, ZSelectConfig, ZSelectControl, ZSelectLabelTemplate, ZSelectLoadMoreEvent, ZSelectMode, ZSelectOption, ZSelectOptionGroup, ZSelectOptionTemplate, ZSelectSize, ZSelectTagColor, ZSelectValidator };
