import * as i2 from '@angular/common';
import { CommonModule, DOCUMENT } from '@angular/common';
import * as i0 from '@angular/core';
import { signal, HostListener, Input, Component, createComponent, Inject, Injectable } from '@angular/core';
import { SdUtilities } from '@sd-angular/core/utilities';
import { trigger, transition, style, animate } from '@angular/animations';

class SdToastComponent {
    notifyService;
    data;
    isExpanded = signal(false);
    MAX_SHOW = 2;
    // --- Logic Timer ---
    timer;
    start;
    remaining;
    constructor(notifyService) {
        this.notifyService = notifyService;
    }
    ngOnInit() {
        // Khởi tạo thời gian còn lại bằng duration ban đầu
        this.remaining = this.data.duration;
        // Bắt đầu đếm ngược ngay khi hiện ra
        this.resumeTimer();
    }
    ngOnDestroy() {
        clearTimeout(this.timer);
    }
    // --- Logic Pause/Resume ---
    pauseTimer() {
        if (this.timer) {
            // Xóa timer hiện tại
            clearTimeout(this.timer);
            this.timer = null;
            // Tính toán thời gian đã trôi qua để trừ đi
            this.remaining -= Date.now() - this.start;
        }
    }
    resumeTimer() {
        // Chỉ chạy tiếp nếu còn thời gian và timer chưa chạy
        if (this.remaining > 0 && !this.timer) {
            this.start = Date.now();
            this.timer = setTimeout(() => {
                this.close();
            }, this.remaining);
        }
    }
    // --- Logic cũ ---
    close() {
        this.notifyService.remove(this.data.id);
    }
    onActionClick() {
        this.data.onAction?.();
    }
    toggleExpand() {
        this.isExpanded.update(v => !v);
    }
    get isMultiMessage() {
        return Array.isArray(this.data.message);
    }
    get messages() {
        return this.data.message;
    }
    get displayMessages() {
        const msgs = this.messages;
        if (this.isExpanded())
            return msgs;
        return msgs.slice(0, this.MAX_SHOW);
    }
    get restCount() {
        return this.messages.length - this.MAX_SHOW;
    }
    get hasMore() {
        return this.isMultiMessage && this.messages.length > this.MAX_SHOW;
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdToastComponent, deps: [{ token: SdNotifyService }], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: SdToastComponent, isStandalone: true, selector: "sd-toast", inputs: { data: "data" }, host: { listeners: { "mouseenter": "pauseTimer()", "mouseleave": "resumeTimer()" }, properties: { "@toastAnimation": "true", "class": "\"bg-white sd-toast\"" } }, ngImport: i0, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\r\n\r\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\r\n  @switch (data.type) {\r\n    @case ('success') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\r\n    }\r\n    @case ('info') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\r\n    }\r\n    @case ('warning') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\r\n    }\r\n    @case ('error') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\r\n    }\r\n  }\r\n</div>\r\n\r\n<div class=\"sd-toast__content\">\r\n  <div class=\"sd-toast__header\">\r\n    <strong class=\"sd-toast__title\">{{ data.title || (data.type | titlecase) }}</strong>\r\n    <button class=\"sd-toast__close\" (click)=\"close()\">\u2715</button>\r\n  </div>\r\n\r\n  <div class=\"sd-toast__body\">\r\n    @if (!isMultiMessage) {\r\n      <div [innerHTML]=\"data.message\"></div>\r\n    } \r\n    @else {\r\n      <ul class=\"msg-list\">\r\n        @for (msg of displayMessages; track msg) {\r\n          <li [innerHTML]=\"'- ' + msg\"></li>\r\n        }\r\n      </ul>\r\n\r\n      @if (hasMore) {\r\n        <button type=\"button\" \r\n                class=\"toggle-more btn-link\" \r\n                [class]=\"'text-' + data.type\" \r\n                (click)=\"toggleExpand()\">\r\n          {{ isExpanded() ? 'Show less' : 'Show more (' + restCount + ')' }}\r\n        </button>\r\n      }\r\n    }\r\n  </div>\r\n\r\n  @if (data.actionLabel) {\r\n    <div class=\"sd-toast__actions\">\r\n      <button class=\"btn-action\" \r\n              [class]=\"'bg-' + data.type + '-light text-' + data.type\"\r\n              (click)=\"onActionClick()\">\r\n        {{ data.actionLabel }}\r\n      </button>\r\n    </div>\r\n  }\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.TitleCasePipe, name: "titlecase" }], animations: [
            trigger('toastAnimation', [
                transition(':enter', [
                    style({ transform: 'translateX(100%)', opacity: 0 }),
                    animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
                ]),
                transition(':leave', [
                    animate('200ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
                ])
            ])
        ] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdToastComponent, decorators: [{
            type: Component,
            args: [{ selector: 'sd-toast', standalone: true, imports: [CommonModule], animations: [
                        trigger('toastAnimation', [
                            transition(':enter', [
                                style({ transform: 'translateX(100%)', opacity: 0 }),
                                animate('300ms ease-out', style({ transform: 'translateX(0)', opacity: 1 }))
                            ]),
                            transition(':leave', [
                                animate('200ms ease-in', style({ transform: 'translateX(100%)', opacity: 0 }))
                            ])
                        ])
                    ], host: {
                        '[@toastAnimation]': 'true',
                        '[class]': '"bg-white sd-toast"'
                    }, template: "<div class=\"sd-toast__bar\" [class]=\"'bg-' + data.type\"></div>\r\n\r\n<div class=\"sd-toast__icon\" [class]=\"'text-' + data.type\">\r\n  @switch (data.type) {\r\n    @case ('success') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z\"/></svg>\r\n    }\r\n    @case ('info') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\"/></svg>\r\n    }\r\n    @case ('warning') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z\"/></svg>\r\n    }\r\n    @case ('error') {\r\n      <svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>\r\n    }\r\n  }\r\n</div>\r\n\r\n<div class=\"sd-toast__content\">\r\n  <div class=\"sd-toast__header\">\r\n    <strong class=\"sd-toast__title\">{{ data.title || (data.type | titlecase) }}</strong>\r\n    <button class=\"sd-toast__close\" (click)=\"close()\">\u2715</button>\r\n  </div>\r\n\r\n  <div class=\"sd-toast__body\">\r\n    @if (!isMultiMessage) {\r\n      <div [innerHTML]=\"data.message\"></div>\r\n    } \r\n    @else {\r\n      <ul class=\"msg-list\">\r\n        @for (msg of displayMessages; track msg) {\r\n          <li [innerHTML]=\"'- ' + msg\"></li>\r\n        }\r\n      </ul>\r\n\r\n      @if (hasMore) {\r\n        <button type=\"button\" \r\n                class=\"toggle-more btn-link\" \r\n                [class]=\"'text-' + data.type\" \r\n                (click)=\"toggleExpand()\">\r\n          {{ isExpanded() ? 'Show less' : 'Show more (' + restCount + ')' }}\r\n        </button>\r\n      }\r\n    }\r\n  </div>\r\n\r\n  @if (data.actionLabel) {\r\n    <div class=\"sd-toast__actions\">\r\n      <button class=\"btn-action\" \r\n              [class]=\"'bg-' + data.type + '-light text-' + data.type\"\r\n              (click)=\"onActionClick()\">\r\n        {{ data.actionLabel }}\r\n      </button>\r\n    </div>\r\n  }\r\n</div>", styles: ["@charset \"UTF-8\";:host{display:flex;width:350px;border-radius:8px;box-shadow:0 4px 12px #00000026;margin-bottom:12px;overflow:hidden;position:relative;font-family:Roboto,sans-serif;pointer-events:auto}.sd-toast__bar{width:6px;flex-shrink:0}.sd-toast__icon{padding:12px 0 0 12px;flex-shrink:0}.sd-toast__icon svg{width:24px;height:24px}.sd-toast__content{flex-grow:1;padding:12px;display:flex;flex-direction:column}.sd-toast__header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:4px}.sd-toast__title{font-size:16px;font-weight:600}.sd-toast__close{background:none;border:none;font-size:16px;cursor:pointer;line-height:1;padding:0;opacity:.5;transition:opacity .2s}.sd-toast__close:hover{opacity:1}.sd-toast__body{font-size:14px;line-height:1.4}.sd-toast__actions{display:flex;justify-content:flex-end;margin-top:8px}.msg-list{padding-left:0;list-style:none;margin:0}.toggle-more{background:none;border:none;padding:0;font:inherit;cursor:pointer;font-size:13px;margin-top:4px;font-weight:500;text-align:left}.toggle-more:hover{text-decoration:underline}.toggle-more:focus-visible{outline:2px solid currentColor;outline-offset:2px}.btn-action{border:none;padding:6px 12px;border-radius:4px;font-weight:600;cursor:pointer;font-size:13px;transition:filter .2s}.btn-action:hover{filter:brightness(.95)}\n"] }]
        }], ctorParameters: () => [{ type: SdNotifyService }], propDecorators: { data: [{
                type: Input,
                args: [{ required: true }]
            }], pauseTimer: [{
                type: HostListener,
                args: ['mouseenter']
            }], resumeTimer: [{
                type: HostListener,
                args: ['mouseleave']
            }] } });

class SdToastContainerComponent {
    // 1. Khai báo biến để nhận Signal từ Service
    // Khởi tạo mặc định là mảng rỗng để không bị lỗi null
    toasts = signal([]);
    // 2. XÓA constructor inject SdNotifyService
    constructor() { }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdToastContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: SdToastContainerComponent, isStandalone: true, selector: "sd-toast-container", ngImport: i0, template: `
    <div class="toast-container">
      <sd-toast *ngFor="let toast of toasts()" [data]="toast"> </sd-toast>
    </div>
  `, isInline: true, styles: [".toast-container{position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;pointer-events:none}sd-toast{pointer-events:auto}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: SdToastComponent, selector: "sd-toast", inputs: ["data"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdToastContainerComponent, decorators: [{
            type: Component,
            args: [{ selector: 'sd-toast-container', standalone: true, imports: [CommonModule, SdToastComponent], template: `
    <div class="toast-container">
      <sd-toast *ngFor="let toast of toasts()" [data]="toast"> </sd-toast>
    </div>
  `, styles: [".toast-container{position:fixed;top:20px;right:20px;z-index:9999;display:flex;flex-direction:column;pointer-events:none}sd-toast{pointer-events:auto}\n"] }]
        }], ctorParameters: () => [] });

class SdNotifyService {
    appRef;
    injector;
    document;
    toasts = signal([]);
    // Constants
    #DEBOUNCE_TIME = 500;
    #DEFAULT_SUCCESS_DURATION = 3000;
    #DEFAULT_BUFFERED_DURATION = 5000;
    #MAX_TOASTS = 5;
    // State
    #buffer = {};
    #timers = {};
    constructor(appRef, injector, document) {
        this.appRef = appRef;
        this.injector = injector;
        this.document = document;
        this.#initContainer();
    }
    #initContainer() {
        const componentRef = createComponent(SdToastContainerComponent, {
            environmentInjector: this.injector,
        });
        componentRef.instance.toasts = this.toasts;
        this.appRef.attachView(componentRef.hostView);
        const domElem = componentRef.hostView.rootNodes[0];
        this.document.body.appendChild(domElem);
    }
    // Public API
    success(message, option) {
        this.#addImmediate('success', message, option);
    }
    info(message, option) {
        this.#addImmediate('info', message, option);
    }
    warning(message, option) {
        this.#addToBuffer('warning', message, option);
    }
    error(message, option) {
        this.#addToBuffer('error', message, option);
    }
    remove(id) {
        this.toasts.update((current) => current.filter((t) => t.id !== id));
    }
    clearAll() {
        this.toasts.set([]);
        this.#clearAllTimers();
    }
    clearByType(type) {
        this.toasts.update((current) => current.filter((t) => t.type !== type));
    }
    // Private helpers
    #addImmediate(type, message, option) {
        const newToast = {
            id: SdUtilities.generateUuid(),
            type,
            message,
            title: option?.title,
            duration: option?.duration ?? this.#DEFAULT_SUCCESS_DURATION,
            actionLabel: option?.actionLabel,
            onAction: option?.onAction
        };
        this.toasts.update((current) => {
            const updated = [newToast, ...current];
            return updated.slice(0, this.#MAX_TOASTS);
        });
    }
    #addToBuffer(type, message, option) {
        if (!this.#buffer[type]) {
            this.#buffer[type] = [];
        }
        const msgs = Array.isArray(message) ? message : [message];
        this.#buffer[type].push(...msgs);
        // Clear existing timer and set new one
        if (this.#timers[type]) {
            clearTimeout(this.#timers[type]);
        }
        this.#timers[type] = setTimeout(() => {
            this.#flushBuffer(type, option);
        }, this.#DEBOUNCE_TIME);
    }
    #flushBuffer(type, option) {
        const messages = [...new Set(this.#buffer[type])];
        // Cleanup
        this.#buffer[type] = [];
        this.#timers[type] = null;
        if (messages.length === 0)
            return;
        const typeLabel = type === 'error' ? 'Error' : 'Warning';
        const title = option?.title ?? typeLabel;
        const finalTitle = messages.length > 1 ? `${title} (${messages.length})` : title;
        const newToast = {
            id: SdUtilities.generateUuid(),
            type,
            message: messages.length === 1 ? messages[0] : messages,
            title: finalTitle,
            duration: option?.duration ?? this.#DEFAULT_BUFFERED_DURATION,
            actionLabel: option?.actionLabel,
            onAction: option?.onAction
        };
        this.toasts.update((current) => {
            const updated = [newToast, ...current];
            return updated.slice(0, this.#MAX_TOASTS);
        });
    }
    #clearAllTimers() {
        Object.values(this.#timers).forEach(timer => {
            if (timer)
                clearTimeout(timer);
        });
        this.#timers = {};
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdNotifyService, deps: [{ token: i0.ApplicationRef }, { token: i0.EnvironmentInjector }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdNotifyService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: SdNotifyService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root',
                }]
        }], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }, { type: Document, decorators: [{
                    type: Inject,
                    args: [DOCUMENT]
                }] }] });

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

export { SdNotifyService };
//# sourceMappingURL=sd-angular-core-services-notify.mjs.map
