import * as i0 from '@angular/core';
import { output, input, model, computed, signal, forwardRef, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
import { zTransform, zMergeClasses, zCreateEvent } from '@shival99/z-ui/utils';
import { cva } from 'class-variance-authority';

/** Maximum character length for inner text */
const Z_SWITCH_INNER_TEXT_MAX_LENGTH = 8;

const zSwitchVariants = cva([
    'relative inline-flex shrink-0 cursor-pointer items-center rounded-full',
    'transition-colors duration-200',
    'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
    'disabled:cursor-not-allowed disabled:opacity-50',
    'bg-input',
    'data-[state=checked]:bg-primary',
    '[--z-wave-color:var(--color-primary)]',
], {
    variants: {
        zSize: {
            sm: 'h-5 w-9',
            default: 'h-6 w-11',
            lg: 'h-7 w-14',
        },
        zMode: {
            default: '',
            inner: 'overflow-hidden',
        },
    },
    compoundVariants: [
        { zMode: 'inner', zSize: 'sm', class: 'min-w-[2.875rem] h-[1.375rem]' },
        { zMode: 'inner', zSize: 'default', class: 'min-w-[3.375rem] h-[1.625rem]' },
        { zMode: 'inner', zSize: 'lg', class: 'min-w-[3.875rem] h-[1.875rem]' },
    ],
    defaultVariants: {
        zSize: 'default',
        zMode: 'default',
    },
});
const zSwitchThumbVariants = cva([
    'pointer-events-none flex items-center justify-center rounded-full bg-white ring-0',
    'shadow-[0_2px_4px_rgba(0,0,0,0.2)] transition-all duration-200',
    'absolute top-1/2 -translate-y-1/2 z-10',
], {
    variants: {
        zSize: {
            sm: 'size-4',
            default: 'size-5',
            lg: 'size-6',
        },
        zMode: {
            default: '',
            inner: '',
        },
    },
    compoundVariants: [
        { zMode: 'default', zSize: 'sm', class: 'left-0.5 data-[state=checked]:translate-x-4' },
        { zMode: 'default', zSize: 'default', class: 'left-0.5 data-[state=checked]:translate-x-5' },
        { zMode: 'default', zSize: 'lg', class: 'left-0.5 data-[state=checked]:translate-x-7' },
        {
            zMode: 'inner',
            zSize: 'sm',
            class: 'size-[1.125rem] left-[0.125rem] data-[state=checked]:left-[calc(100%-1.25rem)]',
        },
        {
            zMode: 'inner',
            zSize: 'default',
            class: 'size-[1.375rem] left-[0.125rem] data-[state=checked]:left-[calc(100%-1.5rem)]',
        },
        {
            zMode: 'inner',
            zSize: 'lg',
            class: 'size-[1.625rem] left-[0.125rem] data-[state=checked]:left-[calc(100%-1.75rem)]',
        },
    ],
    defaultVariants: {
        zSize: 'default',
        zMode: 'default',
    },
});
const zSwitchLabelVariants = cva('select-none cursor-pointer peer-disabled:cursor-not-allowed peer-disabled:opacity-70', {
    variants: {
        zSize: {
            sm: 'text-xs',
            default: 'text-sm',
            lg: 'text-base',
        },
    },
    defaultVariants: {
        zSize: 'default',
    },
});
// Text hiển thị bên TRÁI (khi checked, thumb ở phải)
const zSwitchInnerLeftVariants = cva([
    'absolute left-0 top-1/2 -translate-y-1/2 text-white font-medium select-none',
    'truncate transition-opacity duration-200',
], {
    variants: {
        zSize: {
            sm: 'text-[0.5625rem] pl-[0.3125rem] max-w-[calc(100%-1.375rem)]',
            default: 'text-[0.625rem] pl-[0.375rem] max-w-[calc(100%-1.625rem)]',
            lg: 'text-[0.6875rem] pl-[0.4375rem] max-w-[calc(100%-1.875rem)]',
        },
    },
    defaultVariants: {
        zSize: 'default',
    },
});
// Text hiển thị bên PHẢI (khi unchecked, thumb ở trái)
const zSwitchInnerRightVariants = cva([
    'absolute right-0 top-1/2 -translate-y-1/2 text-white font-medium select-none',
    'truncate transition-opacity duration-200',
], {
    variants: {
        zSize: {
            sm: 'text-[0.5625rem] pr-[0.3125rem] max-w-[calc(100%-1.375rem)]',
            default: 'text-[0.625rem] pr-[0.375rem] max-w-[calc(100%-1.625rem)]',
            lg: 'text-[0.6875rem] pr-[0.4375rem] max-w-[calc(100%-1.875rem)]',
        },
    },
    defaultVariants: {
        zSize: 'default',
    },
});

class ZSwitchComponent {
    zChange = output();
    zOnBlur = output();
    zOnFocus = output();
    zEvent = output();
    class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
    zSwitchClass = input('', ...(ngDevMode ? [{ debugName: "zSwitchClass" }] : []));
    zThumbClass = input('', ...(ngDevMode ? [{ debugName: "zThumbClass" }] : []));
    zSize = input('default', ...(ngDevMode ? [{ debugName: "zSize" }] : []));
    zMode = input('default', ...(ngDevMode ? [{ debugName: "zMode" }] : []));
    zLabel = input('', ...(ngDevMode ? [{ debugName: "zLabel" }] : []));
    zText = input('', ...(ngDevMode ? [{ debugName: "zText" }] : []));
    zCheckedText = input('ON', ...(ngDevMode ? [{ debugName: "zCheckedText" }] : []));
    zUncheckedText = input('OFF', ...(ngDevMode ? [{ debugName: "zUncheckedText" }] : []));
    zCheckedIcon = input(null, ...(ngDevMode ? [{ debugName: "zCheckedIcon" }] : []));
    zUncheckedIcon = input(null, ...(ngDevMode ? [{ debugName: "zUncheckedIcon" }] : []));
    zDisabled = input(false, { ...(ngDevMode ? { debugName: "zDisabled" } : {}), transform: zTransform });
    zLoading = input(false, { ...(ngDevMode ? { debugName: "zLoading" } : {}), transform: zTransform });
    zTextPosition = input('right', ...(ngDevMode ? [{ debugName: "zTextPosition" }] : []));
    zWave = input(true, { ...(ngDevMode ? { debugName: "zWave" } : {}), transform: zTransform });
    zChecked = model(false, ...(ngDevMode ? [{ debugName: "zChecked" }] : []));
    isInnerMode = computed(() => this.zMode() === 'inner', ...(ngDevMode ? [{ debugName: "isInnerMode" }] : []));
    _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
    isDisabled = computed(() => this.zDisabled() || this._disabled() || this.zLoading(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
    hostClasses = computed(() => {
        const hasLabel = !!this.zLabel();
        if (hasLabel) {
            return zMergeClasses('flex flex-col gap-2', this.class());
        }
        return zMergeClasses('inline-flex items-center gap-3', this.class());
    }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
    switchClasses = computed(() => zMergeClasses(zSwitchVariants({ zSize: this.zSize(), zMode: this.zMode() }), this.zSwitchClass()), ...(ngDevMode ? [{ debugName: "switchClasses" }] : []));
    thumbClasses = computed(() => zMergeClasses(zSwitchThumbVariants({ zSize: this.zSize(), zMode: this.zMode() }), this.zThumbClass()), ...(ngDevMode ? [{ debugName: "thumbClasses" }] : []));
    labelClasses = computed(() => zSwitchLabelVariants({ zSize: this.zSize() }), ...(ngDevMode ? [{ debugName: "labelClasses" }] : []));
    switchState = computed(() => (this.zChecked() ? 'checked' : 'unchecked'), ...(ngDevMode ? [{ debugName: "switchState" }] : []));
    innerLeftClasses = computed(() => zSwitchInnerLeftVariants({ zSize: this.zSize() }), ...(ngDevMode ? [{ debugName: "innerLeftClasses" }] : []));
    innerRightClasses = computed(() => zSwitchInnerRightVariants({ zSize: this.zSize() }), ...(ngDevMode ? [{ debugName: "innerRightClasses" }] : []));
    currentThumbIcon = computed(() => {
        if (this.zChecked()) {
            return this.zCheckedIcon();
        }
        return this.zUncheckedIcon();
    }, ...(ngDevMode ? [{ debugName: "currentThumbIcon" }] : []));
    displayCheckedText = computed(() => {
        const text = this.zCheckedText();
        if (text.length > Z_SWITCH_INNER_TEXT_MAX_LENGTH) {
            return text.slice(0, Z_SWITCH_INNER_TEXT_MAX_LENGTH - 1) + '…';
        }
        return text;
    }, ...(ngDevMode ? [{ debugName: "displayCheckedText" }] : []));
    displayUncheckedText = computed(() => {
        const text = this.zUncheckedText();
        if (text.length > Z_SWITCH_INNER_TEXT_MAX_LENGTH) {
            return text.slice(0, Z_SWITCH_INNER_TEXT_MAX_LENGTH - 1) + '…';
        }
        return text;
    }, ...(ngDevMode ? [{ debugName: "displayUncheckedText" }] : []));
    loadingIconSize = computed(() => {
        const size = this.zSize();
        if (size === 'sm') {
            return '10';
        }
        if (size === 'lg') {
            return '16';
        }
        return '12';
    }, ...(ngDevMode ? [{ debugName: "loadingIconSize" }] : []));
    _onChange = () => { };
    _onTouched = () => { };
    writeValue(value) {
        this.zChecked.set(!!value);
    }
    registerOnChange(fn) {
        this._onChange = fn;
    }
    registerOnTouched(fn) {
        this._onTouched = fn;
    }
    setDisabledState(isDisabled) {
        this._disabled.set(isDisabled);
    }
    onFocus(event) {
        this.zOnFocus.emit(event);
        this.zEvent.emit(zCreateEvent('focus', event));
    }
    onBlur(event) {
        this.zOnBlur.emit(event);
        this.zEvent.emit(zCreateEvent('blur', event));
        this._onTouched();
    }
    onSwitchClick(event) {
        if (this.isDisabled()) {
            return;
        }
        const newValue = !this.zChecked();
        this.zChecked.set(newValue);
        this.zChange.emit(newValue);
        this._onChange(newValue);
        this._onTouched();
        // Wave effect
        if (this.zWave()) {
            const target = event.currentTarget;
            const button = target.tagName === 'BUTTON' ? target : target.closest('button');
            if (button) {
                this._triggerWaveEffect(button);
            }
        }
    }
    _triggerWaveEffect(el) {
        const waveEl = document.createElement('span');
        waveEl.className = 'z-animate-wave';
        el.appendChild(waveEl);
        el.classList.add('z-wave-active');
        const onWaveAnimationEnd = (event) => {
            if (event.animationName !== 'z-fade-effect') {
                return;
            }
            waveEl.remove();
            el.classList.remove('z-wave-active');
            waveEl.removeEventListener('animationend', onWaveAnimationEnd);
        };
        waveEl.addEventListener('animationend', onWaveAnimationEnd);
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZSwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZSwitchComponent, isStandalone: true, selector: "z-switch", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zSwitchClass: { classPropertyName: "zSwitchClass", publicName: "zSwitchClass", isSignal: true, isRequired: false, transformFunction: null }, zThumbClass: { classPropertyName: "zThumbClass", publicName: "zThumbClass", isSignal: true, isRequired: false, transformFunction: null }, zSize: { classPropertyName: "zSize", publicName: "zSize", isSignal: true, isRequired: false, transformFunction: null }, zMode: { classPropertyName: "zMode", publicName: "zMode", isSignal: true, isRequired: false, transformFunction: null }, zLabel: { classPropertyName: "zLabel", publicName: "zLabel", isSignal: true, isRequired: false, transformFunction: null }, zText: { classPropertyName: "zText", publicName: "zText", isSignal: true, isRequired: false, transformFunction: null }, zCheckedText: { classPropertyName: "zCheckedText", publicName: "zCheckedText", isSignal: true, isRequired: false, transformFunction: null }, zUncheckedText: { classPropertyName: "zUncheckedText", publicName: "zUncheckedText", isSignal: true, isRequired: false, transformFunction: null }, zCheckedIcon: { classPropertyName: "zCheckedIcon", publicName: "zCheckedIcon", isSignal: true, isRequired: false, transformFunction: null }, zUncheckedIcon: { classPropertyName: "zUncheckedIcon", publicName: "zUncheckedIcon", isSignal: true, isRequired: false, transformFunction: null }, zDisabled: { classPropertyName: "zDisabled", publicName: "zDisabled", isSignal: true, isRequired: false, transformFunction: null }, zLoading: { classPropertyName: "zLoading", publicName: "zLoading", isSignal: true, isRequired: false, transformFunction: null }, zTextPosition: { classPropertyName: "zTextPosition", publicName: "zTextPosition", isSignal: true, isRequired: false, transformFunction: null }, zWave: { classPropertyName: "zWave", publicName: "zWave", isSignal: true, isRequired: false, transformFunction: null }, zChecked: { classPropertyName: "zChecked", publicName: "zChecked", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { zChange: "zChange", zOnBlur: "zOnBlur", zOnFocus: "zOnFocus", zEvent: "zEvent", zChecked: "zCheckedChange" }, host: { properties: { "class": "hostClasses()" } }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => ZSwitchComponent),
                multi: true,
            },
        ], ngImport: i0, template: "<!-- Label above -->\n@if (zLabel()) {\n  <label class=\"text-xs leading-none font-medium\">{{ zLabel() }}</label>\n}\n\n<div class=\"inline-flex items-center gap-3\">\n  @if (zText() && zTextPosition() === 'left') {\n    <label [class]=\"labelClasses()\" (click)=\"onSwitchClick($event)\">{{ zText() }}</label>\n  }\n\n  <button\n    type=\"button\"\n    role=\"switch\"\n    [class]=\"switchClasses()\"\n    [attr.aria-checked]=\"zChecked()\"\n    [attr.data-state]=\"switchState()\"\n    [attr.data-loading]=\"zLoading()\"\n    [disabled]=\"isDisabled()\"\n    (click)=\"onSwitchClick($event)\"\n    (focus)=\"onFocus($event)\"\n    (blur)=\"onBlur($event)\">\n    <!-- Thumb (handle) -->\n    <span [class]=\"thumbClasses()\" [attr.data-state]=\"switchState()\" [attr.data-loading]=\"zLoading()\">\n      @if (zLoading()) {\n        <z-icon zType=\"lucideLoader2\" [zSize]=\"loadingIconSize()\" class=\"text-muted-foreground animate-spin\" />\n      }\n      @if (!zLoading() && currentThumbIcon(); as thumbIcon) {\n        <z-icon [zType]=\"thumbIcon\" [zSize]=\"loadingIconSize()\" class=\"text-muted-foreground\" />\n      }\n    </span>\n    <!-- Inner text mode -->\n    @if (isInnerMode()) {\n      <!-- Checked text: LEFT side (visible when checked, thumb is on right) -->\n      <span [class]=\"innerLeftClasses()\" [class.opacity-100]=\"zChecked()\" [class.opacity-0]=\"!zChecked()\">\n        {{ displayCheckedText() }}\n      </span>\n      <!-- Unchecked text: RIGHT side (visible when unchecked, thumb is on left) -->\n      <span [class]=\"innerRightClasses()\" [class.opacity-100]=\"!zChecked()\" [class.opacity-0]=\"zChecked()\">\n        {{ displayUncheckedText() }}\n      </span>\n    }\n  </button>\n\n  @if (zText() && zTextPosition() === 'right') {\n    <label [class]=\"labelClasses()\" (click)=\"onSwitchClick($event)\">{{ zText() }}</label>\n  }\n</div>\n", dependencies: [{ kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZSwitchComponent, decorators: [{
            type: Component,
            args: [{ selector: 'z-switch', imports: [ZIconComponent], standalone: true, providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => ZSwitchComponent),
                            multi: true,
                        },
                    ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
                        '[class]': 'hostClasses()',
                    }, template: "<!-- Label above -->\n@if (zLabel()) {\n  <label class=\"text-xs leading-none font-medium\">{{ zLabel() }}</label>\n}\n\n<div class=\"inline-flex items-center gap-3\">\n  @if (zText() && zTextPosition() === 'left') {\n    <label [class]=\"labelClasses()\" (click)=\"onSwitchClick($event)\">{{ zText() }}</label>\n  }\n\n  <button\n    type=\"button\"\n    role=\"switch\"\n    [class]=\"switchClasses()\"\n    [attr.aria-checked]=\"zChecked()\"\n    [attr.data-state]=\"switchState()\"\n    [attr.data-loading]=\"zLoading()\"\n    [disabled]=\"isDisabled()\"\n    (click)=\"onSwitchClick($event)\"\n    (focus)=\"onFocus($event)\"\n    (blur)=\"onBlur($event)\">\n    <!-- Thumb (handle) -->\n    <span [class]=\"thumbClasses()\" [attr.data-state]=\"switchState()\" [attr.data-loading]=\"zLoading()\">\n      @if (zLoading()) {\n        <z-icon zType=\"lucideLoader2\" [zSize]=\"loadingIconSize()\" class=\"text-muted-foreground animate-spin\" />\n      }\n      @if (!zLoading() && currentThumbIcon(); as thumbIcon) {\n        <z-icon [zType]=\"thumbIcon\" [zSize]=\"loadingIconSize()\" class=\"text-muted-foreground\" />\n      }\n    </span>\n    <!-- Inner text mode -->\n    @if (isInnerMode()) {\n      <!-- Checked text: LEFT side (visible when checked, thumb is on right) -->\n      <span [class]=\"innerLeftClasses()\" [class.opacity-100]=\"zChecked()\" [class.opacity-0]=\"!zChecked()\">\n        {{ displayCheckedText() }}\n      </span>\n      <!-- Unchecked text: RIGHT side (visible when unchecked, thumb is on left) -->\n      <span [class]=\"innerRightClasses()\" [class.opacity-100]=\"!zChecked()\" [class.opacity-0]=\"zChecked()\">\n        {{ displayUncheckedText() }}\n      </span>\n    }\n  </button>\n\n  @if (zText() && zTextPosition() === 'right') {\n    <label [class]=\"labelClasses()\" (click)=\"onSwitchClick($event)\">{{ zText() }}</label>\n  }\n</div>\n" }]
        }], propDecorators: { zChange: [{ type: i0.Output, args: ["zChange"] }], zOnBlur: [{ type: i0.Output, args: ["zOnBlur"] }], zOnFocus: [{ type: i0.Output, args: ["zOnFocus"] }], zEvent: [{ type: i0.Output, args: ["zEvent"] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zSwitchClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSwitchClass", required: false }] }], zThumbClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "zThumbClass", required: false }] }], zSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "zSize", required: false }] }], zMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "zMode", required: false }] }], zLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLabel", required: false }] }], zText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zText", required: false }] }], zCheckedText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCheckedText", required: false }] }], zUncheckedText: [{ type: i0.Input, args: [{ isSignal: true, alias: "zUncheckedText", required: false }] }], zCheckedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCheckedIcon", required: false }] }], zUncheckedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "zUncheckedIcon", required: false }] }], zDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDisabled", required: false }] }], zLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLoading", required: false }] }], zTextPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTextPosition", required: false }] }], zWave: [{ type: i0.Input, args: [{ isSignal: true, alias: "zWave", required: false }] }], zChecked: [{ type: i0.Input, args: [{ isSignal: true, alias: "zChecked", required: false }] }, { type: i0.Output, args: ["zCheckedChange"] }] } });

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

export { ZSwitchComponent, Z_SWITCH_INNER_TEXT_MAX_LENGTH, zSwitchInnerLeftVariants, zSwitchInnerRightVariants, zSwitchLabelVariants, zSwitchThumbVariants, zSwitchVariants };
//# sourceMappingURL=shival99-z-ui-components-z-switch.mjs.map
