import * as i0 from '@angular/core';
import { InjectionToken, inject, ViewContainerRef, LOCALE_ID, viewChild, EventEmitter, input, booleanAttribute, computed, Output, ViewEncapsulation, ChangeDetectionStrategy, Component, Directive, contentChildren, ElementRef, signal, effect, untracked, forwardRef, Injectable } from '@angular/core';
import { formatDate } from '@angular/common';
import { Overlay, OverlayModule } from '@angular/cdk/overlay';
import { TemplatePortal } from '@angular/cdk/portal';
import { Option } from '@ngstarter-ui/components/option';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Subject, takeUntil } from 'rxjs';
import { Button } from '@ngstarter-ui/components/button';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
import { FormField } from '@ngstarter-ui/components/form-field';

const TIMEPICKER_CONFIG = new InjectionToken('TIMEPICKER_CONFIG');

class Timepicker {
    _overlay = inject(Overlay);
    _viewContainerRef = inject(ViewContainerRef);
    _localeId = inject(LOCALE_ID);
    _config = inject(TIMEPICKER_CONFIG, { optional: true });
    _template = viewChild.required('timepickerTemplate');
    _panel = viewChild('panel', ...(ngDevMode ? [{ debugName: "_panel" }] : /* istanbul ignore next */ []));
    opened = new EventEmitter();
    closed = new EventEmitter();
    _overlayRef = null;
    _input = null;
    disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    interval = input(typeof this._config?.interval === 'string' ? parseInt(this._config.interval, 10) : (this._config?.interval ?? 30), { ...(ngDevMode ? { debugName: "interval" } : /* istanbul ignore next */ {}), transform: (value) => typeof value === 'string' ? parseInt(value, 10) : value });
    _timeOptions = computed(() => {
        const input = this._input;
        const min = input?.min();
        const max = input?.max();
        const minTime = min ? this._toTimeString(min) : null;
        const maxTime = max ? this._toTimeString(max) : null;
        const options = [];
        const interval = Math.max(1, this.interval() || 1);
        for (let h = 0; h < 24; h++) {
            for (let m = 0; m < 60; m += interval) {
                const value = h.toString().padStart(2, '0') + ':' + m.toString().padStart(2, '0');
                if (minTime && value < minTime) {
                    continue;
                }
                if (maxTime && value > maxTime) {
                    continue;
                }
                const date = new Date();
                date.setHours(h, m, 0, 0);
                const label = formatDate(date, 'shortTime', this._localeId);
                options.push({ label, value });
            }
        }
        return options;
    }, ...(ngDevMode ? [{ debugName: "_timeOptions" }] : /* istanbul ignore next */ []));
    _toTimeString(value) {
        if (value instanceof Date) {
            return value.getHours().toString().padStart(2, '0') + ':' +
                value.getMinutes().toString().padStart(2, '0');
        }
        if (typeof value === 'string') {
            const input = this._input;
            if (input && !/^\d{2}:\d{2}$/.test(value)) {
                return input._parseValue(value);
            }
        }
        return value || '';
    }
    constructor() { }
    _registerInput(input) {
        this._input = input;
    }
    open() {
        const input = this._input;
        const disabled = typeof this.disabled === 'function' ? this.disabled() : this.disabled;
        const inputDisabled = typeof input?.disabled === 'function' ? input.disabled() : input?.disabled;
        if (this._overlayRef || !input || disabled || inputDisabled) {
            return;
        }
        const strategy = this._overlay.position()
            .flexibleConnectedTo(input.getConnectedOverlayOrigin())
            .withPositions([
            { originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' },
            { originX: 'start', originY: 'top', overlayX: 'start', overlayY: 'bottom' }
        ]);
        this._overlayRef = this._overlay.create({
            positionStrategy: strategy,
            hasBackdrop: true,
            backdropClass: 'cdk-overlay-transparent-backdrop',
            scrollStrategy: this._overlay.scrollStrategies.reposition(),
            width: input.getOverlayWidth()
        });
        this._overlayRef.backdropClick().subscribe(() => this.close());
        const portal = new TemplatePortal(this._template(), this._viewContainerRef);
        this._overlayRef.attach(portal);
        this.opened.emit();
        this._scrollToSelected();
    }
    close() {
        if (this._overlayRef) {
            this._overlayRef.detach();
            this._overlayRef.dispose();
            this._overlayRef = null;
            this.closed.emit();
        }
    }
    _isSelected(value) {
        return this._input?.value === value || this._input?._modelValue === value;
    }
    _scrollToSelected() {
        setTimeout(() => {
            const panel = this._panel()?.nativeElement;
            if (!panel) {
                return;
            }
            const selectedOption = panel.querySelector('.ngs-option-selected');
            if (!selectedOption) {
                return;
            }
            const optionOffset = selectedOption.offsetTop;
            const optionHeight = selectedOption.offsetHeight;
            const panelScrollTop = panel.scrollTop;
            const panelHeight = panel.offsetHeight;
            if (optionOffset < panelScrollTop) {
                panel.scrollTop = optionOffset;
            }
            else if (optionOffset + optionHeight > panelScrollTop + panelHeight) {
                panel.scrollTop = optionOffset - panelHeight + optionHeight;
            }
        });
    }
    _selectValue(value) {
        const input = this._input;
        if (input) {
            input._setValue(value);
        }
        this.close();
    }
    isOpen() {
        return !!this._overlayRef;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Timepicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: Timepicker, isStandalone: true, selector: "ngs-timepicker", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, interval: { classPropertyName: "interval", publicName: "interval", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed" }, viewQueries: [{ propertyName: "_template", first: true, predicate: ["timepickerTemplate"], descendants: true, isSignal: true }, { propertyName: "_panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }], exportAs: ["ngsTimepicker"], ngImport: i0, template: "<ng-template #timepickerTemplate>\n  <div class=\"ngs-timepicker-panel\" role=\"listbox\" #panel>\n    <div class=\"h-full overflow-y-auto\">\n      <div class=\"ngs-timepicker-content\">\n        @for (option of _timeOptions(); track option.value) {\n          <ngs-option [value]=\"option.value\"\n                      [selected]=\"_isSelected(option.value)\"\n                      (mousedown)=\"$event.preventDefault()\"\n                      (onSelectionChange)=\"_selectValue(option.value)\">\n            {{ option.label }}\n          </ngs-option>\n        }\n      </div>\n    </div>\n  </div>\n</ng-template>\n", styles: [".ngs-timepicker-panel{background:var(--ngs-dropdown-bg);box-shadow:var(--ngs-dropdown-shadow);border-radius:var(--ngs-dropdown-radius);outline:var(--ngs-dropdown-border);width:100%;min-width:120px;max-height:256px;position:relative;transform-origin:top;animation:ngs-timepicker-panel-showing .15s cubic-bezier(0,0,.2,1);overflow:hidden}.ngs-timepicker-panel .ngs-timepicker-content{padding:var(--ngs-timepicker-content-padding, var(--ngs-dropdown-padding, calc(var(--spacing, .25rem) * 2)))}@keyframes ngs-timepicker-panel-showing{0%{opacity:0;transform:scaleY(.8)}to{opacity:1;transform:scaleY(1)}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "component", type: Option, selector: "ngs-option", inputs: ["value", "disabled", "selected"], outputs: ["onSelectionChange"], exportAs: ["ngsOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: Timepicker, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-timepicker', standalone: true, imports: [OverlayModule, Option], exportAs: 'ngsTimepicker', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<ng-template #timepickerTemplate>\n  <div class=\"ngs-timepicker-panel\" role=\"listbox\" #panel>\n    <div class=\"h-full overflow-y-auto\">\n      <div class=\"ngs-timepicker-content\">\n        @for (option of _timeOptions(); track option.value) {\n          <ngs-option [value]=\"option.value\"\n                      [selected]=\"_isSelected(option.value)\"\n                      (mousedown)=\"$event.preventDefault()\"\n                      (onSelectionChange)=\"_selectValue(option.value)\">\n            {{ option.label }}\n          </ngs-option>\n        }\n      </div>\n    </div>\n  </div>\n</ng-template>\n", styles: [".ngs-timepicker-panel{background:var(--ngs-dropdown-bg);box-shadow:var(--ngs-dropdown-shadow);border-radius:var(--ngs-dropdown-radius);outline:var(--ngs-dropdown-border);width:100%;min-width:120px;max-height:256px;position:relative;transform-origin:top;animation:ngs-timepicker-panel-showing .15s cubic-bezier(0,0,.2,1);overflow:hidden}.ngs-timepicker-panel .ngs-timepicker-content{padding:var(--ngs-timepicker-content-padding, var(--ngs-dropdown-padding, calc(var(--spacing, .25rem) * 2)))}@keyframes ngs-timepicker-panel-showing{0%{opacity:0;transform:scaleY(.8)}to{opacity:1;transform:scaleY(1)}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], ctorParameters: () => [], propDecorators: { _template: [{ type: i0.ViewChild, args: ['timepickerTemplate', { isSignal: true }] }], _panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], opened: [{
                type: Output
            }], closed: [{
                type: Output
            }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], interval: [{ type: i0.Input, args: [{ isSignal: true, alias: "interval", required: false }] }] } });

class TimepickerToggleIcon {
    constructor() { }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerToggleIcon, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: TimepickerToggleIcon, isStandalone: true, selector: "[ngsTimepickerToggleIcon]", ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerToggleIcon, decorators: [{
            type: Directive,
            args: [{
                    selector: '[ngsTimepickerToggleIcon]',
                    standalone: true
                }]
        }], ctorParameters: () => [] });

class TimepickerToggle {
    _stateChanges = new Subject();
    customIcons = contentChildren(TimepickerToggleIcon, { ...(ngDevMode ? { debugName: "customIcons" } : /* istanbul ignore next */ {}), descendants: true });
    timepicker = input(null, { ...(ngDevMode ? { debugName: "timepicker" } : /* istanbul ignore next */ {}), alias: 'for' });
    disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: coerceBooleanProperty });
    ngOnDestroy() {
        this._stateChanges.complete();
    }
    _open(event) {
        const timepicker = this.timepicker();
        const timepickerDisabled = typeof timepicker?.disabled === 'function' ? timepicker.disabled() : timepicker?.disabled;
        const disabled = this.disabled() || timepickerDisabled;
        if (timepicker && !disabled) {
            timepicker.open();
            event.stopPropagation();
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerToggle, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: TimepickerToggle, isStandalone: true, selector: "ngs-timepicker-toggle", inputs: { timepicker: { classPropertyName: "timepicker", publicName: "for", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.ngs-timepicker-toggle-active": "timepicker()?.isOpen()" }, classAttribute: "ngs-timepicker-toggle" }, queries: [{ propertyName: "customIcons", predicate: TimepickerToggleIcon, descendants: true, isSignal: true }], exportAs: ["ngsTimepickerToggle"], ngImport: i0, template: "<button\n  ngsIconButton\n  type=\"button\"\n  [attr.aria-label]=\"'Open timepicker'\"\n  [disabled]=\"(disabled() || timepicker()?.disabled()) || null\"\n  (click)=\"_open($event)\"\n>\n  <ng-content select=\"[ngsTimepickerToggleIcon]\"/>\n  @if (customIcons().length === 0) {\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n      <path fill=\"currentColor\"\n            d=\"M12 5a8.5 8.5 0 1 1 0 17a8.5 8.5 0 0 1 0-17m0 1.5a7 7 0 1 0 0 14a7 7 0 0 0 0-14M12 8a.75.75 0 0 1 .743.648l.007.102v4.5a.75.75 0 0 1-1.493.102l-.007-.102v-4.5A.75.75 0 0 1 12 8m7.147-2.886l.083.06l1.158.964a.75.75 0 0 1-.877 1.212l-.082-.06l-1.159-.964a.75.75 0 0 1 .877-1.212M14.25 2.5a.75.75 0 0 1 .102 1.493L14.25 4h-4.5a.75.75 0 0 1-.102-1.493L9.75 2.5z\"/>\n    </svg>\n  }\n</button>\n", styles: [":host{display:contents}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: Button, selector: "    button[ngsButton], button[ngsIconButton],    a[ngsButton], a[ngsIconButton]  ", inputs: ["ngsButton", "ngsIconButton", "loading", "disabled", "disabledInteractive", "disableRipple", "reverse", "fullWidth", "hideTextOnMobile"], exportAs: ["ngsButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerToggle, decorators: [{
            type: Component,
            args: [{ selector: 'ngs-timepicker-toggle', exportAs: 'ngsTimepickerToggle', standalone: true, imports: [Button], changeDetection: ChangeDetectionStrategy.OnPush, host: {
                        'class': 'ngs-timepicker-toggle',
                        '[class.ngs-timepicker-toggle-active]': 'timepicker()?.isOpen()',
                    }, template: "<button\n  ngsIconButton\n  type=\"button\"\n  [attr.aria-label]=\"'Open timepicker'\"\n  [disabled]=\"(disabled() || timepicker()?.disabled()) || null\"\n  (click)=\"_open($event)\"\n>\n  <ng-content select=\"[ngsTimepickerToggleIcon]\"/>\n  @if (customIcons().length === 0) {\n    <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n      <path fill=\"currentColor\"\n            d=\"M12 5a8.5 8.5 0 1 1 0 17a8.5 8.5 0 0 1 0-17m0 1.5a7 7 0 1 0 0 14a7 7 0 0 0 0-14M12 8a.75.75 0 0 1 .743.648l.007.102v4.5a.75.75 0 0 1-1.493.102l-.007-.102v-4.5A.75.75 0 0 1 12 8m7.147-2.886l.083.06l1.158.964a.75.75 0 0 1-.877 1.212l-.082-.06l-1.159-.964a.75.75 0 0 1 .877-1.212M14.25 2.5a.75.75 0 0 1 .102 1.493L14.25 4h-4.5a.75.75 0 0 1-.102-1.493L9.75 2.5z\"/>\n    </svg>\n  }\n</button>\n", styles: [":host{display:contents}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
        }], propDecorators: { customIcons: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TimepickerToggleIcon), { ...{ descendants: true }, isSignal: true }] }], timepicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "for", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });

class TimepickerInput {
    _elementRef = inject((ElementRef));
    _formField = inject(FormField, { optional: true });
    _localeId = inject(LOCALE_ID);
    _disabledByCva = signal(false, ...(ngDevMode ? [{ debugName: "_disabledByCva" }] : /* istanbul ignore next */ []));
    _disabledInput = input(false, { ...(ngDevMode ? { debugName: "_disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
        transform: booleanAttribute });
    disabled = computed(() => this._disabledInput() || this._disabledByCva(), ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
    max = input(null, { ...(ngDevMode ? { debugName: "max" } : /* istanbul ignore next */ {}), transform: (value) => value });
    min = input(null, { ...(ngDevMode ? { debugName: "min" } : /* istanbul ignore next */ {}), transform: (value) => value });
    openOnClick = input(true, { ...(ngDevMode ? { debugName: "openOnClick" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
    ngsTimepicker = input.required(...(ngDevMode ? [{ debugName: "ngsTimepicker" }] : /* istanbul ignore next */ []));
    _timepicker;
    _onChange = () => { };
    _onTouched = () => { };
    _validatorOnChange = () => { };
    _modelValue = '';
    _destroyed = new Subject();
    _timepickerDestroyed = new Subject();
    _isTimepickerOpen = false;
    _lastExternalDate = null;
    constructor() {
        effect(() => {
            this.min();
            this.max();
            this._validatorOnChange();
        });
        effect(() => {
            const picker = this.ngsTimepicker();
            untracked(() => {
                this._registerTimepicker(picker);
            });
        });
    }
    ngOnDestroy() {
        this._destroyed.next();
        this._destroyed.complete();
    }
    _registerTimepicker(value) {
        if (value && value !== this._timepicker) {
            this._timepickerDestroyed.next();
            this._timepicker = value;
            this._timepicker._registerInput(this);
            this._timepicker.opened
                .pipe(takeUntil(this._timepickerDestroyed), takeUntil(this._destroyed))
                .subscribe(() => {
                this._isTimepickerOpen = true;
            });
            this._timepicker.closed
                .pipe(takeUntil(this._timepickerDestroyed), takeUntil(this._destroyed))
                .subscribe(() => {
                this._isTimepickerOpen = false;
                this._validatorOnChange();
                this._updateNativeValidity(this._doValidate(this._modelValue));
            });
        }
    }
    writeValue(value) {
        this._modelValue = this._toTimeString(value);
        this._lastExternalDate = value instanceof Date ? value : null;
        this._elementRef.nativeElement.value = this._formatValue(value);
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    registerOnValidatorChange(fn) {
        this._validatorOnChange = fn;
    }
    validate(control) {
        if (this._isTimepickerOpen) {
            return null;
        }
        const value = control.value;
        const errors = this._doValidate(value);
        this._updateNativeValidity(errors);
        return errors;
    }
    _doValidate(value) {
        if (!value) {
            return null;
        }
        const parsedValue = this._parseValue(value);
        const isValid = /^\d{2}:\d{2}$/.test(parsedValue);
        if (!isValid) {
            return { 'ngsTimepickerParse': { text: value } };
        }
        const min = this.min();
        if (min) {
            const minTime = this._toTimeString(min);
            if (parsedValue < minTime) {
                return { 'ngsTimepickerMin': { min: minTime, actual: parsedValue } };
            }
        }
        const max = this.max();
        if (max) {
            const maxTime = this._toTimeString(max);
            if (parsedValue > maxTime) {
                return { 'ngsTimepickerMax': { max: maxTime, actual: parsedValue } };
            }
        }
        return null;
    }
    _updateNativeValidity(errors) {
        const element = this._elementRef.nativeElement;
        if (typeof element.setCustomValidity !== 'function') {
            return;
        }
        if (!errors) {
            element.setCustomValidity('');
        }
        else {
            const errorKey = Object.keys(errors)[0];
            element.setCustomValidity(errorKey);
        }
    }
    setDisabledState(isDisabled) {
        this._disabledByCva.set(isDisabled);
    }
    _onInput(value) {
        this._modelValue = this._parseValue(value);
        const originalValue = (this._lastExternalDate && /^\d{2}:\d{2}$/.test(this._modelValue))
            ? this._mergeTimeIntoDate(this._modelValue, this._lastExternalDate)
            : this._modelValue;
        this._onChange(originalValue);
        this._formField?.control()?.stateChanges.set(undefined);
        if (!this._isTimepickerOpen) {
            this._updateNativeValidity(this._doValidate(this._modelValue));
        }
    }
    _onBlur() {
        this._onTouched();
        // After blur, re-format the input field to a clean localized string if it's a valid time
        this._elementRef.nativeElement.value = this._formatValue(this._modelValue);
    }
    _toTimeString(value) {
        if (value instanceof Date) {
            return value.getHours().toString().padStart(2, '0') + ':' +
                value.getMinutes().toString().padStart(2, '0');
        }
        if (typeof value === 'string') {
            if (!/^\d{2}:\d{2}$/.test(value)) {
                return this._parseValue(value);
            }
        }
        return value || '';
    }
    _onFocus() {
        if (this.openOnClick()) {
            this.ngsTimepicker().open();
        }
    }
    _onClick() {
        if (this.openOnClick()) {
            this.ngsTimepicker().open();
        }
    }
    _setValue(value) {
        const originalValue = (this._lastExternalDate)
            ? this._mergeTimeIntoDate(value, this._lastExternalDate)
            : value;
        this._modelValue = value;
        this._elementRef.nativeElement.value = this._formatValue(value);
        this._onChange(originalValue);
        this._formField?.control()?.stateChanges.set(undefined);
        if (!this._isTimepickerOpen) {
            this._updateNativeValidity(this._doValidate(value));
        }
        this._elementRef.nativeElement.focus();
    }
    _mergeTimeIntoDate(time, date) {
        const [h, m] = time.split(':').map(v => parseInt(v, 10));
        const newDate = new Date(date);
        newDate.setHours(h, m, 0, 0);
        return newDate;
    }
    _formatValue(value) {
        if (value instanceof Date) {
            return formatDate(value, 'shortTime', this._localeId);
        }
        if (typeof value !== 'string' || !value || !value.includes(':')) {
            return value || '';
        }
        const [h, m] = value.split(':');
        const date = new Date();
        date.setHours(+h, +m, 0, 0);
        return formatDate(date, 'shortTime', this._localeId);
    }
    _parseValue(value) {
        if (!value) {
            return '';
        }
        if (value instanceof Date) {
            return value.getHours().toString().padStart(2, '0') + ':' +
                value.getMinutes().toString().padStart(2, '0');
        }
        if (typeof value !== 'string') {
            return '';
        }
        if (/^\d{1,2}:\d{2}$/.test(value)) {
            const [h, m] = value.split(':');
            return h.padStart(2, '0') + ':' + m.padStart(2, '0');
        }
        if (/^\d{1,2}$/.test(value)) {
            return value;
        }
        let tryValue = value;
        if (/^\d{1,2}\s?(am|pm)$/i.test(value)) {
            tryValue = value.replace(/(am|pm)/i, ':00 $1');
        }
        const date = new Date('1970-01-01 ' + tryValue);
        if (!isNaN(date.getTime())) {
            const h = date.getHours().toString().padStart(2, '0');
            const m = date.getMinutes().toString().padStart(2, '0');
            return `${h}:${m}`;
        }
        return value;
    }
    get value() {
        return this._modelValue;
    }
    getConnectedOverlayOrigin() {
        if (this._formField) {
            return this._formField.wrapper();
        }
        return this._elementRef;
    }
    getOverlayWidth() {
        if (this._formField) {
            return this._formField.wrapper().nativeElement.getBoundingClientRect().width;
        }
        return 'auto';
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.4", type: TimepickerInput, isStandalone: true, selector: "input[ngsTimepicker]", inputs: { _disabledInput: { classPropertyName: "_disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, openOnClick: { classPropertyName: "openOnClick", publicName: "openOnClick", isSignal: true, isRequired: false, transformFunction: null }, ngsTimepicker: { classPropertyName: "ngsTimepicker", publicName: "ngsTimepicker", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "input": "_onInput($any($event.target).value)", "blur": "_onBlur()", "focus": "_onFocus()", "click": "_onClick()" }, properties: { "disabled": "disabled() || null" }, classAttribute: "ngs-timepicker-input" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => TimepickerInput),
                multi: true
            },
            {
                provide: NG_VALIDATORS,
                useExisting: forwardRef(() => TimepickerInput),
                multi: true
            }
        ], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerInput, decorators: [{
            type: Directive,
            args: [{
                    selector: 'input[ngsTimepicker]',
                    standalone: true,
                    providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => TimepickerInput),
                            multi: true
                        },
                        {
                            provide: NG_VALIDATORS,
                            useExisting: forwardRef(() => TimepickerInput),
                            multi: true
                        }
                    ],
                    host: {
                        'class': 'ngs-timepicker-input',
                        '[disabled]': 'disabled() || null',
                        '(input)': '_onInput($any($event.target).value)',
                        '(blur)': '_onBlur()',
                        '(focus)': '_onFocus()',
                        '(click)': '_onClick()',
                    }
                }]
        }], ctorParameters: () => [], propDecorators: { _disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], openOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOnClick", required: false }] }], ngsTimepicker: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngsTimepicker", required: true }] }] } });

class TimepickerIntl {
    changes = new Subject();
    openTimepickerLabel = 'Open timepicker';
    closeTimepickerLabel = 'Close timepicker';
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerIntl, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerIntl, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: TimepickerIntl, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { TIMEPICKER_CONFIG, Timepicker, TimepickerInput, TimepickerIntl, TimepickerToggle, TimepickerToggleIcon };
//# sourceMappingURL=ngstarter-ui-components-timepicker.mjs.map
