import * as i0 from '@angular/core';
import { InjectionToken, inject, input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, Injector, PLATFORM_ID, NgZone, Injectable, makeEnvironmentProviders } from '@angular/core';
import { NgxSonnerToaster, toast } from '@shival99/ngx-sonner';
import { ZThemeService, ZTranslateService } from '@shival99/z-ui/services';
import { zMergeClasses } from '@shival99/z-ui/utils';
import { cva } from 'class-variance-authority';
import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
import { Overlay, OverlayConfig } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';

/* eslint-disable @typescript-eslint/no-explicit-any */
const Z_TOAST_DATA = new InjectionToken('Z_TOAST_DATA');
const Z_TOAST_ANIMATION_DURATION = 200;
const Z_TOASTER_CONFIG = new InjectionToken('Z_TOASTER_CONFIG');
const Z_TOASTER_DEFAULT_CONFIG = {
    zTheme: 'system',
    zPosition: 'top-right',
    zRichColors: true,
    zExpand: true,
    zDuration: 2500,
    zVisibleToasts: 3,
    zCloseButton: true,
    zDir: 'auto',
};

const zToastVariants = cva('group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg', {
    variants: {
        zVariant: {
            default: 'group-[.toaster]:bg-background group-[.toaster]:text-foreground',
            success: 'group-[.toaster]:bg-green-50 group-[.toaster]:text-green-800 group-[.toaster]:border-green-200 dark:group-[.toaster]:bg-green-950 dark:group-[.toaster]:text-green-200 dark:group-[.toaster]:border-green-800',
            error: 'group-[.toaster]:bg-red-50 group-[.toaster]:text-red-800 group-[.toaster]:border-red-200 dark:group-[.toaster]:bg-red-950 dark:group-[.toaster]:text-red-200 dark:group-[.toaster]:border-red-800',
            warning: 'group-[.toaster]:bg-amber-50 group-[.toaster]:text-amber-800 group-[.toaster]:border-amber-200 dark:group-[.toaster]:bg-amber-950 dark:group-[.toaster]:text-amber-200 dark:group-[.toaster]:border-amber-800',
            info: 'group-[.toaster]:bg-blue-50 group-[.toaster]:text-blue-800 group-[.toaster]:border-blue-200 dark:group-[.toaster]:bg-blue-950 dark:group-[.toaster]:text-blue-200 dark:group-[.toaster]:border-blue-800',
        },
    },
    defaultVariants: {
        zVariant: 'default',
    },
});

class ZToastComponent {
    _themeService = inject(ZThemeService);
    _config = inject(Z_TOASTER_CONFIG, { optional: true }) ?? Z_TOASTER_DEFAULT_CONFIG;
    class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
    zVariant = input('default', ...(ngDevMode ? [{ debugName: "zVariant" }] : []));
    zTheme = input(...(ngDevMode ? [undefined, { debugName: "zTheme" }] : []));
    zPosition = input(...(ngDevMode ? [undefined, { debugName: "zPosition" }] : []));
    zRichColors = input(...(ngDevMode ? [undefined, { debugName: "zRichColors" }] : []));
    zExpand = input(...(ngDevMode ? [undefined, { debugName: "zExpand" }] : []));
    zDuration = input(...(ngDevMode ? [undefined, { debugName: "zDuration" }] : []));
    zVisibleToasts = input(...(ngDevMode ? [undefined, { debugName: "zVisibleToasts" }] : []));
    zCloseButton = input(...(ngDevMode ? [undefined, { debugName: "zCloseButton" }] : []));
    zToastOptions = input({}, ...(ngDevMode ? [{ debugName: "zToastOptions" }] : []));
    zDir = input(...(ngDevMode ? [undefined, { debugName: "zDir" }] : []));
    effectiveTheme = computed(() => this.zTheme() ?? this._config.zTheme ?? 'system', ...(ngDevMode ? [{ debugName: "effectiveTheme" }] : []));
    effectivePosition = computed(() => this.zPosition() ?? this._config.zPosition ?? 'bottom-right', ...(ngDevMode ? [{ debugName: "effectivePosition" }] : []));
    effectiveRichColors = computed(() => this.zRichColors() ?? this._config.zRichColors ?? true, ...(ngDevMode ? [{ debugName: "effectiveRichColors" }] : []));
    effectiveExpand = computed(() => this.zExpand() ?? this._config.zExpand ?? false, ...(ngDevMode ? [{ debugName: "effectiveExpand" }] : []));
    effectiveDuration = computed(() => this.zDuration() ?? this._config.zDuration ?? 4000, ...(ngDevMode ? [{ debugName: "effectiveDuration" }] : []));
    effectiveVisibleToasts = computed(() => this.zVisibleToasts() ?? this._config.zVisibleToasts ?? 3, ...(ngDevMode ? [{ debugName: "effectiveVisibleToasts" }] : []));
    effectiveCloseButton = computed(() => this.zCloseButton() ?? this._config.zCloseButton ?? false, ...(ngDevMode ? [{ debugName: "effectiveCloseButton" }] : []));
    effectiveDir = computed(() => this.zDir() ?? this._config.zDir ?? 'auto', ...(ngDevMode ? [{ debugName: "effectiveDir" }] : []));
    zClasses = computed(() => zMergeClasses('toaster group', zToastVariants({ zVariant: this.zVariant() }), this.class()), ...(ngDevMode ? [{ debugName: "zClasses" }] : []));
    detectTheme = computed(() => {
        const theme = this.effectiveTheme();
        if (theme !== 'system') {
            return theme;
        }
        return this._themeService.isDark() ? 'dark' : 'light';
    }, ...(ngDevMode ? [{ debugName: "detectTheme" }] : []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.9", type: ZToastComponent, isStandalone: true, selector: "z-toast, z-toaster", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zVariant: { classPropertyName: "zVariant", publicName: "zVariant", isSignal: true, isRequired: false, transformFunction: null }, zTheme: { classPropertyName: "zTheme", publicName: "zTheme", isSignal: true, isRequired: false, transformFunction: null }, zPosition: { classPropertyName: "zPosition", publicName: "zPosition", isSignal: true, isRequired: false, transformFunction: null }, zRichColors: { classPropertyName: "zRichColors", publicName: "zRichColors", isSignal: true, isRequired: false, transformFunction: null }, zExpand: { classPropertyName: "zExpand", publicName: "zExpand", isSignal: true, isRequired: false, transformFunction: null }, zDuration: { classPropertyName: "zDuration", publicName: "zDuration", isSignal: true, isRequired: false, transformFunction: null }, zVisibleToasts: { classPropertyName: "zVisibleToasts", publicName: "zVisibleToasts", isSignal: true, isRequired: false, transformFunction: null }, zCloseButton: { classPropertyName: "zCloseButton", publicName: "zCloseButton", isSignal: true, isRequired: false, transformFunction: null }, zToastOptions: { classPropertyName: "zToastOptions", publicName: "zToastOptions", isSignal: true, isRequired: false, transformFunction: null }, zDir: { classPropertyName: "zDir", publicName: "zDir", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["zToast"], ngImport: i0, template: "<ngx-sonner-toaster\n  [theme]=\"detectTheme()\"\n  [class]=\"zClasses()\"\n  [position]=\"effectivePosition()\"\n  [richColors]=\"effectiveRichColors()\"\n  [expand]=\"effectiveExpand()\"\n  [duration]=\"effectiveDuration()\"\n  [visibleToasts]=\"effectiveVisibleToasts()\"\n  [closeButton]=\"effectiveCloseButton()\"\n  [toastOptions]=\"zToastOptions()\"\n  [dir]=\"effectiveDir()\" />\n", dependencies: [{ kind: "component", type: NgxSonnerToaster, selector: "ngx-sonner-toaster", inputs: ["invert", "theme", "position", "hotKey", "richColors", "expand", "duration", "visibleToasts", "closeButton", "toastOptions", "offset", "dir", "class", "style"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZToastComponent, decorators: [{
            type: Component,
            args: [{ selector: 'z-toast, z-toaster', imports: [NgxSonnerToaster], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'zToast', template: "<ngx-sonner-toaster\n  [theme]=\"detectTheme()\"\n  [class]=\"zClasses()\"\n  [position]=\"effectivePosition()\"\n  [richColors]=\"effectiveRichColors()\"\n  [expand]=\"effectiveExpand()\"\n  [duration]=\"effectiveDuration()\"\n  [visibleToasts]=\"effectiveVisibleToasts()\"\n  [closeButton]=\"effectiveCloseButton()\"\n  [toastOptions]=\"zToastOptions()\"\n  [dir]=\"effectiveDir()\" />\n" }]
        }], propDecorators: { class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "zVariant", required: false }] }], zTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTheme", required: false }] }], zPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "zPosition", required: false }] }], zRichColors: [{ type: i0.Input, args: [{ isSignal: true, alias: "zRichColors", required: false }] }], zExpand: [{ type: i0.Input, args: [{ isSignal: true, alias: "zExpand", required: false }] }], zDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDuration", required: false }] }], zVisibleToasts: [{ type: i0.Input, args: [{ isSignal: true, alias: "zVisibleToasts", required: false }] }], zCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCloseButton", required: false }] }], zToastOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "zToastOptions", required: false }] }], zDir: [{ type: i0.Input, args: [{ isSignal: true, alias: "zDir", required: false }] }] } });

class ZToastService {
    _overlay = inject(Overlay);
    _injector = inject(Injector);
    _platformId = inject(PLATFORM_ID);
    _document = inject(DOCUMENT);
    _ngZone = inject(NgZone);
    _providedConfig = inject(Z_TOASTER_CONFIG, { optional: true });
    _zTranslate = inject(ZTranslateService);
    _overlayRef = null;
    _toasterAttached = false;
    _mutationObserver = null;
    create(config) {
        if (this._toasterAttached) {
            return;
        }
        this._attachToaster(config);
    }
    show(message, options) {
        this._ensureToasterAttached();
        this._moveToTop();
        return toast(this._translate(message), options);
    }
    success(message, options) {
        this._ensureToasterAttached();
        this._moveToTop();
        return toast.success(this._translate(message), options);
    }
    error(message, options) {
        this._ensureToasterAttached();
        this._moveToTop();
        return toast.error(this._translate(message), options);
    }
    warning(message, options) {
        this._ensureToasterAttached();
        this._moveToTop();
        return toast.warning(this._translate(message), options);
    }
    info(message, options) {
        this._ensureToasterAttached();
        this._moveToTop();
        return toast.info(this._translate(message), options);
    }
    loading(message, options) {
        this._ensureToasterAttached();
        this._moveToTop();
        return toast.loading(this._translate(message), options);
    }
    promise(promise, messages) {
        this._ensureToasterAttached();
        this._moveToTop();
        return toast.promise(promise, messages);
    }
    custom(config, options) {
        this._ensureToasterAttached();
        this._moveToTop();
        // Sinh ID duy nhất nếu chưa được cấu hình
        const toastId = options?.id ?? Math.random().toString(36).substring(2, 9);
        const updatedConfig = {
            ...config,
            toastId,
        };
        // Gọi phương thức custom của ngx-sonner với unstyled: true để tùy biến hoàn toàn UI
        return toast.custom(ZToastCustomComponent, {
            ...options,
            unstyled: true,
            id: toastId,
            componentProps: {
                config: updatedConfig,
            },
        });
    }
    dismiss(toastId) {
        toast.dismiss(toastId);
    }
    dismissAll() {
        toast.dismiss();
    }
    destroy() {
        this._disconnectObserver();
        if (this._overlayRef) {
            this._overlayRef.dispose();
            this._overlayRef = null;
            this._toasterAttached = false;
        }
    }
    ngOnDestroy() {
        this.destroy();
    }
    _ensureToasterAttached() {
        if (!this._toasterAttached) {
            this._attachToaster();
        }
    }
    _moveToTop() {
        const wrapperElement = this._overlayRef?.overlayElement?.parentElement;
        if (!wrapperElement?.hasAttribute('popover')) {
            return;
        }
        try {
            wrapperElement.hidePopover();
            wrapperElement.showPopover();
        }
        catch {
            console.warn('Popover API not supported on this browser.');
        }
    }
    _setupOverlayObserver() {
        if (!isPlatformBrowser(this._platformId)) {
            return;
        }
        if (this._mutationObserver) {
            return;
        }
        const overlayContainer = this._document.querySelector('.cdk-overlay-container');
        if (!overlayContainer) {
            return;
        }
        this._ngZone.runOutsideAngular(() => {
            this._mutationObserver = new MutationObserver(mutations => {
                const hasNewPopover = mutations.some(mutation => mutation.type === 'childList' &&
                    Array.from(mutation.addedNodes).some(node => node instanceof HTMLElement && node.classList.contains('cdk-overlay-popover')));
                if (hasNewPopover) {
                    this._moveToTop();
                }
            });
            this._mutationObserver.observe(overlayContainer, {
                childList: true,
                subtree: false,
            });
        });
    }
    _disconnectObserver() {
        if (this._mutationObserver) {
            this._mutationObserver.disconnect();
            this._mutationObserver = null;
        }
    }
    _attachToaster(config) {
        if (!isPlatformBrowser(this._platformId)) {
            return;
        }
        if (this._toasterAttached) {
            return;
        }
        this._overlayRef = this._createOverlay();
        if (!this._overlayRef) {
            return;
        }
        const effectiveConfig = {
            ...Z_TOASTER_DEFAULT_CONFIG,
            ...this._providedConfig,
            ...config,
        };
        const injector = Injector.create({
            parent: this._injector,
            providers: [{ provide: Z_TOASTER_CONFIG, useValue: effectiveConfig }],
        });
        const portal = new ComponentPortal(ZToastComponent, null, injector);
        this._overlayRef.attach(portal);
        this._toasterAttached = true;
        this._setupOverlayObserver();
    }
    _createOverlay() {
        if (!isPlatformBrowser(this._platformId)) {
            return null;
        }
        const overlayConfig = new OverlayConfig({
            hasBackdrop: false,
            positionStrategy: this._overlay.position().global(),
            scrollStrategy: this._overlay.scrollStrategies.noop(),
        });
        const overlayRef = this._overlay.create(overlayConfig);
        overlayRef.overlayElement.style.zIndex = '99999';
        return overlayRef;
    }
    _translate(message) {
        if (!message) {
            return message;
        }
        return this._zTranslate.instant(message) || message;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZToastService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZToastService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }] });

class ZToastCustomComponent {
    _toastService = inject(ZToastService);
    config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
    dismiss() {
        const id = this.config().toastId;
        if (id !== undefined) {
            this._toastService.dismiss(id);
        }
    }
    handleAction(action) {
        const id = this.config().toastId;
        if (id !== undefined) {
            // Thực thi callback của nút hành động và tự động đóng toast tương ứng
            action.onClick(id);
            this._toastService.dismiss(id);
        }
    }
    getFeaturedIconName() {
        const { type } = this.config();
        const configIcon = this.config().icon;
        if (configIcon) {
            return configIcon;
        }
        switch (type) {
            case 'success':
                return 'lucideCircleCheck';
            case 'error':
                return 'lucideCircleX';
            case 'warning':
                return 'lucideTriangleAlert';
            case 'info':
                return 'lucideInfo';
            default:
                return 'lucideBell';
        }
    }
    getFeaturedIconContainerClasses() {
        const { type } = this.config();
        // Trả về class styling cho vòng tròn đồng tâm bao quanh icon (Featured Icon)
        switch (type) {
            case 'success':
                return 'bg-emerald-50 text-emerald-600 dark:bg-emerald-950/30 dark:text-emerald-400 border border-emerald-100 dark:border-emerald-900/50 ring-4 ring-emerald-500/5';
            case 'error':
                return 'bg-rose-50 text-rose-600 dark:bg-rose-950/30 dark:text-rose-400 border border-rose-100 dark:border-rose-900/50 ring-4 ring-rose-500/5';
            case 'warning':
                return 'bg-amber-50 text-amber-600 dark:bg-amber-950/30 dark:text-amber-400 border border-amber-100 dark:border-amber-900/50 ring-4 ring-amber-500/5';
            case 'info':
                return 'bg-sky-50 text-sky-600 dark:bg-sky-950/30 dark:text-sky-400 border border-sky-100 dark:border-sky-900/50 ring-4 ring-sky-500/5';
            default:
                return 'bg-zinc-50 text-zinc-600 dark:bg-zinc-900 dark:text-zinc-400 border border-zinc-100 dark:border-zinc-800 ring-4 ring-zinc-500/5';
        }
    }
    getActionClasses(action) {
        const type = action.zType || 'primary';
        switch (type) {
            case 'primary':
                return 'text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 dark:hover:text-indigo-300';
            case 'secondary':
                return 'text-zinc-500 hover:text-zinc-600 dark:text-zinc-400 dark:hover:text-zinc-300';
            case 'danger':
                return 'text-rose-600 dark:text-rose-400 hover:text-rose-700 dark:hover:text-rose-300';
            default:
                return 'text-zinc-500 hover:text-zinc-600 dark:text-zinc-400 dark:hover:text-zinc-300';
        }
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZToastCustomComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZToastCustomComponent, isStandalone: true, selector: "z-toast-custom", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div\n  class=\"border-border bg-card relative flex w-full max-w-[480px] flex-col gap-4 rounded-xl border p-4 font-sans shadow-lg md:flex-row md:items-start\"\n  [class.min-w-[340px]]=\"config().type !== 'image'\"\n  [class.md:p-0]=\"config().type === 'image'\"\n  [class.overflow-hidden]=\"config().type === 'image'\">\n  <!-- Content for layout types -->\n  @if (config().type === 'image') {\n    <!-- Style 1: D\u1EA1ng th\u00F4ng b\u00E1o ch\u1EE9a \u1EA3nh phong c\u1EA3nh n\u1EB1m b\u00EAn tr\u00E1i (desktop) ho\u1EB7c b\u00EAn tr\u00EAn (mobile) -->\n    <div class=\"flex w-full flex-col md:flex-row\">\n      <!-- \u1EA2nh tr\u00EAn Desktop -->\n      @if (config().imageUrl) {\n        <div class=\"border-border hidden w-32 shrink-0 overflow-hidden rounded-l-xl border-r md:block\">\n          <img [src]=\"config().imageUrl\" alt=\"Notification image\" class=\"h-full w-full object-cover\" />\n        </div>\n        <!-- \u1EA2nh tr\u00EAn Mobile -->\n        <div class=\"block h-32 w-full overflow-hidden rounded-t-xl md:hidden\">\n          <img [src]=\"config().imageUrl\" alt=\"Notification image\" class=\"h-full w-full object-cover\" />\n        </div>\n      }\n\n      <!-- N\u1ED9i dung ch\u1EEF v\u00E0 c\u00E1c n\u00FAt h\u00E0nh \u0111\u1ED9ng -->\n      <div class=\"flex flex-1 flex-col gap-3 p-4\">\n        <div class=\"flex flex-col gap-1 pr-6\">\n          <p class=\"text-foreground text-sm font-semibold\">{{ config().title }}</p>\n          @if (config().description) {\n            <p class=\"text-muted-foreground text-sm\">{{ config().description }}</p>\n          }\n        </div>\n\n        <!-- N\u00FAt h\u00E0nh \u0111\u1ED9ng -->\n        @if (config().actions && config().actions!.length > 0) {\n          <div class=\"flex gap-3\">\n            @for (action of config().actions; track $index) {\n              <button\n                (click)=\"handleAction(action)\"\n                class=\"cursor-pointer text-sm font-semibold hover:underline\"\n                [class]=\"getActionClasses(action)\">\n                {{ action.label }}\n              </button>\n            }\n          </div>\n        }\n      </div>\n    </div>\n  } @else {\n    <!-- Style 2: C\u00E1c d\u1EA1ng th\u00F4ng b\u00E1o ti\u00EAu chu\u1EA9n (Alert, Avatar, Progress, Default) -->\n\n    <!-- Icon ho\u1EB7c Avatar \u1EDF g\u00F3c tr\u00E1i -->\n    @if (config().type === 'avatar' && config().avatarUrl) {\n      <div class=\"relative flex size-10 shrink-0 rounded-full\">\n        <img\n          [src]=\"config().avatarUrl\"\n          [alt]=\"config().title\"\n          class=\"border-border size-full rounded-full border object-cover\" />\n        @if (config().avatarOnline) {\n          <span\n            class=\"ring-card absolute right-0 bottom-0 flex size-2.5 justify-center rounded-full bg-emerald-500 ring-[1.5px]\"></span>\n        }\n      </div>\n    } @else if (config().type && config().type !== 'default') {\n      <!-- Featured Icon wrapper v\u1EDBi hi\u1EC7u \u1EE9ng vi\u1EC1n \u0111\u1ED3ng t\u00E2m -->\n      <div\n        class=\"relative flex size-10 shrink-0 items-center justify-center rounded-full\"\n        [class]=\"getFeaturedIconContainerClasses()\">\n        <i z-icon [zType]=\"getFeaturedIconName()\" zSize=\"20\" class=\"z-10\"></i>\n      </div>\n    }\n\n    <!-- Ti\u00EAu \u0111\u1EC1, m\u00F4 t\u1EA3 v\u00E0 thanh ti\u1EBFn tr\u00ECnh -->\n    <div class=\"flex flex-1 flex-col gap-3\">\n      <div class=\"flex flex-col gap-1 pr-6\">\n        <p class=\"text-foreground text-sm font-semibold\">{{ config().title }}</p>\n        @if (config().description) {\n          <p class=\"text-muted-foreground text-sm\">{{ config().description }}</p>\n        }\n      </div>\n\n      <!-- D\u1EA1ng Progress bar d\u00E0nh cho ti\u1EBFn tr\u00ECnh upload/t\u1EA3i xu\u1ED1ng -->\n      @if (config().type === 'progress' && config().progress !== undefined) {\n        <div class=\"flex w-full flex-col gap-1.5\">\n          <div class=\"h-2 w-full overflow-hidden rounded-md bg-zinc-100 dark:bg-zinc-800\">\n            <div\n              class=\"bg-primary h-full rounded-md transition-all duration-300\"\n              [style.width.%]=\"config().progress\"></div>\n          </div>\n          <span class=\"text-muted-foreground text-xs font-medium tabular-nums\">\n            {{ config().progress }}% uploaded...\n          </span>\n        </div>\n      }\n\n      <!-- C\u00E1c n\u00FAt h\u00E0nh \u0111\u1ED9ng b\u00EAn d\u01B0\u1EDBi th\u00F4ng b\u00E1o -->\n      @if (config().actions && config().actions!.length > 0) {\n        <div class=\"flex gap-3\">\n          @for (action of config().actions; track $index) {\n            <button\n              (click)=\"handleAction(action)\"\n              class=\"cursor-pointer text-sm font-semibold hover:underline\"\n              [class]=\"getActionClasses(action)\">\n              {{ action.label }}\n            </button>\n          }\n        </div>\n      }\n    </div>\n  }\n\n  <!-- N\u00FAt \u0111\u00F3ng/t\u1EAFt th\u00F4ng b\u00E1o g\u00F3c tr\u00EAn b\u00EAn ph\u1EA3i -->\n  @if (config().closeable !== false) {\n    <button\n      (click)=\"dismiss()\"\n      aria-label=\"Close\"\n      class=\"text-muted-foreground hover:text-foreground absolute top-3 right-3 flex cursor-pointer items-center justify-center rounded-lg p-1.5 transition duration-150 hover:bg-zinc-100 dark:hover:bg-zinc-800\">\n      <i z-icon zType=\"lucideX\" zSize=\"16\"></i>\n    </button>\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: ZToastCustomComponent, decorators: [{
            type: Component,
            args: [{ selector: 'z-toast-custom', imports: [ZIconComponent], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n  class=\"border-border bg-card relative flex w-full max-w-[480px] flex-col gap-4 rounded-xl border p-4 font-sans shadow-lg md:flex-row md:items-start\"\n  [class.min-w-[340px]]=\"config().type !== 'image'\"\n  [class.md:p-0]=\"config().type === 'image'\"\n  [class.overflow-hidden]=\"config().type === 'image'\">\n  <!-- Content for layout types -->\n  @if (config().type === 'image') {\n    <!-- Style 1: D\u1EA1ng th\u00F4ng b\u00E1o ch\u1EE9a \u1EA3nh phong c\u1EA3nh n\u1EB1m b\u00EAn tr\u00E1i (desktop) ho\u1EB7c b\u00EAn tr\u00EAn (mobile) -->\n    <div class=\"flex w-full flex-col md:flex-row\">\n      <!-- \u1EA2nh tr\u00EAn Desktop -->\n      @if (config().imageUrl) {\n        <div class=\"border-border hidden w-32 shrink-0 overflow-hidden rounded-l-xl border-r md:block\">\n          <img [src]=\"config().imageUrl\" alt=\"Notification image\" class=\"h-full w-full object-cover\" />\n        </div>\n        <!-- \u1EA2nh tr\u00EAn Mobile -->\n        <div class=\"block h-32 w-full overflow-hidden rounded-t-xl md:hidden\">\n          <img [src]=\"config().imageUrl\" alt=\"Notification image\" class=\"h-full w-full object-cover\" />\n        </div>\n      }\n\n      <!-- N\u1ED9i dung ch\u1EEF v\u00E0 c\u00E1c n\u00FAt h\u00E0nh \u0111\u1ED9ng -->\n      <div class=\"flex flex-1 flex-col gap-3 p-4\">\n        <div class=\"flex flex-col gap-1 pr-6\">\n          <p class=\"text-foreground text-sm font-semibold\">{{ config().title }}</p>\n          @if (config().description) {\n            <p class=\"text-muted-foreground text-sm\">{{ config().description }}</p>\n          }\n        </div>\n\n        <!-- N\u00FAt h\u00E0nh \u0111\u1ED9ng -->\n        @if (config().actions && config().actions!.length > 0) {\n          <div class=\"flex gap-3\">\n            @for (action of config().actions; track $index) {\n              <button\n                (click)=\"handleAction(action)\"\n                class=\"cursor-pointer text-sm font-semibold hover:underline\"\n                [class]=\"getActionClasses(action)\">\n                {{ action.label }}\n              </button>\n            }\n          </div>\n        }\n      </div>\n    </div>\n  } @else {\n    <!-- Style 2: C\u00E1c d\u1EA1ng th\u00F4ng b\u00E1o ti\u00EAu chu\u1EA9n (Alert, Avatar, Progress, Default) -->\n\n    <!-- Icon ho\u1EB7c Avatar \u1EDF g\u00F3c tr\u00E1i -->\n    @if (config().type === 'avatar' && config().avatarUrl) {\n      <div class=\"relative flex size-10 shrink-0 rounded-full\">\n        <img\n          [src]=\"config().avatarUrl\"\n          [alt]=\"config().title\"\n          class=\"border-border size-full rounded-full border object-cover\" />\n        @if (config().avatarOnline) {\n          <span\n            class=\"ring-card absolute right-0 bottom-0 flex size-2.5 justify-center rounded-full bg-emerald-500 ring-[1.5px]\"></span>\n        }\n      </div>\n    } @else if (config().type && config().type !== 'default') {\n      <!-- Featured Icon wrapper v\u1EDBi hi\u1EC7u \u1EE9ng vi\u1EC1n \u0111\u1ED3ng t\u00E2m -->\n      <div\n        class=\"relative flex size-10 shrink-0 items-center justify-center rounded-full\"\n        [class]=\"getFeaturedIconContainerClasses()\">\n        <i z-icon [zType]=\"getFeaturedIconName()\" zSize=\"20\" class=\"z-10\"></i>\n      </div>\n    }\n\n    <!-- Ti\u00EAu \u0111\u1EC1, m\u00F4 t\u1EA3 v\u00E0 thanh ti\u1EBFn tr\u00ECnh -->\n    <div class=\"flex flex-1 flex-col gap-3\">\n      <div class=\"flex flex-col gap-1 pr-6\">\n        <p class=\"text-foreground text-sm font-semibold\">{{ config().title }}</p>\n        @if (config().description) {\n          <p class=\"text-muted-foreground text-sm\">{{ config().description }}</p>\n        }\n      </div>\n\n      <!-- D\u1EA1ng Progress bar d\u00E0nh cho ti\u1EBFn tr\u00ECnh upload/t\u1EA3i xu\u1ED1ng -->\n      @if (config().type === 'progress' && config().progress !== undefined) {\n        <div class=\"flex w-full flex-col gap-1.5\">\n          <div class=\"h-2 w-full overflow-hidden rounded-md bg-zinc-100 dark:bg-zinc-800\">\n            <div\n              class=\"bg-primary h-full rounded-md transition-all duration-300\"\n              [style.width.%]=\"config().progress\"></div>\n          </div>\n          <span class=\"text-muted-foreground text-xs font-medium tabular-nums\">\n            {{ config().progress }}% uploaded...\n          </span>\n        </div>\n      }\n\n      <!-- C\u00E1c n\u00FAt h\u00E0nh \u0111\u1ED9ng b\u00EAn d\u01B0\u1EDBi th\u00F4ng b\u00E1o -->\n      @if (config().actions && config().actions!.length > 0) {\n        <div class=\"flex gap-3\">\n          @for (action of config().actions; track $index) {\n            <button\n              (click)=\"handleAction(action)\"\n              class=\"cursor-pointer text-sm font-semibold hover:underline\"\n              [class]=\"getActionClasses(action)\">\n              {{ action.label }}\n            </button>\n          }\n        </div>\n      }\n    </div>\n  }\n\n  <!-- N\u00FAt \u0111\u00F3ng/t\u1EAFt th\u00F4ng b\u00E1o g\u00F3c tr\u00EAn b\u00EAn ph\u1EA3i -->\n  @if (config().closeable !== false) {\n    <button\n      (click)=\"dismiss()\"\n      aria-label=\"Close\"\n      class=\"text-muted-foreground hover:text-foreground absolute top-3 right-3 flex cursor-pointer items-center justify-center rounded-lg p-1.5 transition duration-150 hover:bg-zinc-100 dark:hover:bg-zinc-800\">\n      <i z-icon zType=\"lucideX\" zSize=\"16\"></i>\n    </button>\n  }\n</div>\n" }]
        }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });

/**
 * Provides global toast configuration options
 * Use this in app.config.ts: providers: [provideZToast({ zPosition: 'top-right' })]
 *
 * @param config - Partial configuration to override default options
 * @returns EnvironmentProviders for the toast service
 *
 * @example
 * ```typescript
 * // In app.config.ts
 * export const appConfig: ApplicationConfig = {
 *   providers: [
 *     provideZToast({
 *       zPosition: 'top-right',
 *       zDuration: 5000,
 *       zCloseButton: true,
 *     }),
 *   ],
 * };
 * ```
 */
function provideZToast(config) {
    const mergedConfig = {
        ...Z_TOASTER_DEFAULT_CONFIG,
        ...config,
    };
    return makeEnvironmentProviders([{ provide: Z_TOASTER_CONFIG, useValue: mergedConfig }]);
}

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

export { ZToastComponent, ZToastCustomComponent, ZToastService, Z_TOASTER_CONFIG, Z_TOASTER_DEFAULT_CONFIG, Z_TOAST_DATA, provideZToast, zToastVariants };
//# sourceMappingURL=shival99-z-ui-components-z-toast.mjs.map
