import * as i2 from '@angular/cdk/portal';
import { CdkPortal, DomPortalOutlet, PortalModule } from '@angular/cdk/portal';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { viewChild, input, booleanAttribute, computed, output, signal, inject, ViewContainerRef, ApplicationRef, Injector, ChangeDetectorRef, DestroyRef, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
import { SdLoadingService } from '@sdcorejs/angular/services';
import * as uuid from 'uuid';
import { Subject, fromEvent, merge } from 'rxjs';
import { map, startWith, distinctUntilChanged, takeUntil } from 'rxjs/operators';

class SdSideDrawer {
    id = `I${uuid.v4()}`;
    portal = viewChild.required(CdkPortal);
    title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
    width = input('480px', ...(ngDevMode ? [{ debugName: "width" }] : []));
    hideClose = input(false, ...(ngDevMode ? [{ debugName: "hideClose", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
    disableBackdropClose = input(false, ...(ngDevMode ? [{ debugName: "disableBackdropClose", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
    // Custom CSS class added to the root side-drawer container
    drawerClass = input('', ...(ngDevMode ? [{ debugName: "drawerClass" }] : []));
    autoIdInput = input(undefined, ...(ngDevMode ? [{ debugName: "autoIdInput", alias: 'autoId' }] : [{ alias: 'autoId' }]));
    autoId = computed(() => this.autoIdInput() ? `components-side-drawer-${this.autoIdInput()}` : undefined, ...(ngDevMode ? [{ debugName: "autoId" }] : []));
    sdClosed = output();
    #embeddedViewRef;
    #isOpenedSignal = signal(false, ...(ngDevMode ? [{ debugName: "#isOpenedSignal" }] : []));
    #isLoadingSignal = signal(false, ...(ngDevMode ? [{ debugName: "#isLoadingSignal" }] : []));
    isOpened = this.#isOpenedSignal.asReadonly();
    isLoading = this.#isLoadingSignal.asReadonly();
    dataOpened = computed(() => (this.#isOpenedSignal() ? 'true' : 'false'), ...(ngDevMode ? [{ debugName: "dataOpened" }] : []));
    dataLoading = computed(() => (this.#isLoadingSignal() ? 'true' : 'false'), ...(ngDevMode ? [{ debugName: "dataLoading" }] : []));
    isHovered$;
    #destroy$ = new Subject();
    #previousBodyOverflow = null;
    #viewContainerRef = inject(ViewContainerRef);
    #ar = inject(ApplicationRef);
    #injector = inject(Injector);
    #ref = inject(ChangeDetectorRef);
    #loadingService = inject(SdLoadingService);
    #destroyRef = inject(DestroyRef);
    constructor() {
        // Thay thế ngAfterViewInit, tự động chạy nội dung này khi DOM sẵn sàng để render
        afterNextRender(() => {
            // 1. Gắn portal vào body và lưu lại EmbeddedViewRef
            const outlet = new DomPortalOutlet(document.body, this.#ar, this.#injector);
            this.#embeddedViewRef = outlet.attachTemplatePortal(this.portal());
            // 2. Setup sự kiện hover ngay sau khi DOM thật đã được in ra
            this.#setupHoverSubscription();
        });
        // Thay thế ngOnDestroy bằng logic destroy trực tiếp 
        this.#destroyRef.onDestroy(() => {
            this.#destroy$.next();
            this.#destroy$.complete();
            if (this.#embeddedViewRef) {
                this.#embeddedViewRef.destroy();
            }
            if (this.#isOpenedSignal()) {
                if (this.#previousBodyOverflow !== null) {
                    document.body.style.overflow = this.#previousBodyOverflow;
                }
                else {
                    document.body.style.overflow = '';
                }
            }
        });
    }
    open = () => {
        this.#ref.markForCheck();
        this.#isOpenedSignal.set(true);
        // Chặn scroll ở document body
        this.#previousBodyOverflow = document.body.style.overflow;
        document.body.style.overflow = 'hidden';
    };
    close = () => {
        this.#ref.markForCheck();
        this.#isOpenedSignal.set(false);
        this.sdClosed.emit();
        this.stopLoading();
        // Khôi phục lại scroll ở document body
        if (this.#previousBodyOverflow !== null) {
            document.body.style.overflow = this.#previousBodyOverflow;
            this.#previousBodyOverflow = null;
        }
        else {
            document.body.style.overflow = '';
        }
    };
    startLoading = () => {
        this.#isLoadingSignal.set(true);
        this.#loadingService.stop(`#${this.id}`);
        this.#loadingService.start(`#${this.id}`);
    };
    stopLoading = () => {
        this.#isLoadingSignal.set(false);
        this.#loadingService.stop(`#${this.id}`);
    };
    preventScroll = (event) => {
        event.preventDefault();
    };
    #setupHoverSubscription() {
        if (!this.#embeddedViewRef)
            return;
        // 3. Lấy DOM element trực tiếp từ rootNodes của EmbeddedViewRef
        const rootNodes = this.#embeddedViewRef.rootNodes;
        const element = rootNodes.find((node) => node.nodeType === Node.ELEMENT_NODE && node.classList?.contains('sd-side-drawer'));
        if (!element) {
            console.warn('SdSideDrawer: Cannot find sd-side-drawer element to attach hover event');
            return;
        }
        // 4. Gắn event listeners trực tiếp lên element thật
        const mouseEnter$ = fromEvent(element, 'mouseenter').pipe(map(() => true));
        const mouseLeave$ = fromEvent(element, 'mouseleave').pipe(map(() => false));
        this.isHovered$ = merge(mouseEnter$, mouseLeave$).pipe(startWith(false), distinctUntilChanged(), takeUntil(this.#destroy$));
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSideDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.24", type: SdSideDrawer, isStandalone: true, selector: "sd-side-drawer", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, hideClose: { classPropertyName: "hideClose", publicName: "hideClose", isSignal: true, isRequired: false, transformFunction: null }, disableBackdropClose: { classPropertyName: "disableBackdropClose", publicName: "disableBackdropClose", isSignal: true, isRequired: false, transformFunction: null }, drawerClass: { classPropertyName: "drawerClass", publicName: "drawerClass", isSignal: true, isRequired: false, transformFunction: null }, autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sdClosed: "sdClosed" }, viewQueries: [{ propertyName: "portal", first: true, predicate: CdkPortal, descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template cdkPortal>\n  @let _isOpened = isOpened();\n  <div\n    [id]=\"id\"\n    class=\"sd-side-drawer\"\n    [ngStyle]=\"{ width: width() }\"\n    [ngClass]=\"drawerClass()\"\n    [class.sd-side-drawer-active]=\"_isOpened\"\n    [attr.data-autoId]=\"autoId()\"\n    [attr.data-opened]=\"dataOpened()\"\n    [attr.data-loading]=\"dataLoading()\"\n    #drawerContainer>\n    @if (_isOpened) {\n      <ng-container>\n        <div class=\"sd-side-drawer-header\">\n          <div class=\"sd-side-drawer-title\">\n            <ng-content select=\"[sdHeaderLeft]\">\n              {{ title() }}\n            </ng-content>\n          </div>\n          <div class=\"sd-side-drawer-header-actions\">\n            <ng-content select=\"[sdHeaderRight]\"></ng-content>\n            @if (!hideClose()) {\n              <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n                <svg\n                  viewBox=\"0 0 24 24\"\n                  width=\"24\"\n                  height=\"24\"\n                  stroke=\"currentColor\"\n                  stroke-width=\"2\"\n                  fill=\"none\"\n                  stroke-linecap=\"round\"\n                  stroke-linejoin=\"round\">\n                  <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n                  <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n                </svg>\n              </button>\n            }\n          </div>\n        </div>\n        @if (_isOpened) {\n          <div class=\"sd-side-drawer-body\">\n            <div class=\"sd-side-drawer-content\">\n              <ng-content></ng-content>\n            </div>\n          </div>\n        }\n        <div class=\"sd-side-drawer-footer\">\n          <ng-content select=\"[sdFooter]\"></ng-content>\n        </div>\n      </ng-container>\n    }\n  </div>\n  @if (_isOpened) {\n    <div\n      aria-hidden=\"true\"\n      class=\"sd-side-drawer-backdrop\"\n      (click)=\"disableBackdropClose() ? null : close()\"\n      (wheel)=\"preventScroll($event)\"\n      (touchmove)=\"preventScroll($event)\"></div>\n  }\n</ng-template>\n", styles: [".sd-side-drawer{position:fixed;right:0;top:0;bottom:0;background-color:#fff;z-index:999;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translate3d(100%,0,0);transition:all .3s ease-in-out;pointer-events:none;box-shadow:0 .4px .8px #0000001a,0 3px 6px #0003}.sd-side-drawer-active{opacity:1;visibility:visible;pointer-events:all;transform:translateZ(0)}.sd-side-drawer-header{min-height:64px;padding:12px 16px;display:flex;align-items:center;justify-content:space-between}.sd-side-drawer-header-actions{display:flex;align-items:center;gap:8px}.sd-side-drawer-title{font-size:20px;line-height:28px;font-weight:500;flex:1;margin-right:16px}.sd-side-drawer-close-btn{background:transparent;border:none;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--sd-secondary-color, #666);border-radius:50%;transition:background-color .2s,color .2s}.sd-side-drawer-close-btn:hover{background-color:#0000000a;color:var(--sd-primary-color, #333)}.sd-side-drawer-close-btn:focus{outline:none;background-color:#00000014}.sd-side-drawer-body{flex:1;position:relative}.sd-side-drawer-content{position:absolute;padding:0 16px 16px;inset:0;overflow:auto}.sd-side-drawer-footer{border-top:1px solid #dde0e5;padding:8px}.sd-side-drawer-backdrop{background-color:#0006;border:0;outline:none!important;position:fixed;inset:0;z-index:99;width:100%;height:100%;transition:all .3s ease-in-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i2.CdkPortal, selector: "[cdkPortal]", exportAs: ["cdkPortal"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.24", ngImport: i0, type: SdSideDrawer, decorators: [{
            type: Component,
            args: [{ selector: 'sd-side-drawer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, PortalModule], template: "<ng-template cdkPortal>\n  @let _isOpened = isOpened();\n  <div\n    [id]=\"id\"\n    class=\"sd-side-drawer\"\n    [ngStyle]=\"{ width: width() }\"\n    [ngClass]=\"drawerClass()\"\n    [class.sd-side-drawer-active]=\"_isOpened\"\n    [attr.data-autoId]=\"autoId()\"\n    [attr.data-opened]=\"dataOpened()\"\n    [attr.data-loading]=\"dataLoading()\"\n    #drawerContainer>\n    @if (_isOpened) {\n      <ng-container>\n        <div class=\"sd-side-drawer-header\">\n          <div class=\"sd-side-drawer-title\">\n            <ng-content select=\"[sdHeaderLeft]\">\n              {{ title() }}\n            </ng-content>\n          </div>\n          <div class=\"sd-side-drawer-header-actions\">\n            <ng-content select=\"[sdHeaderRight]\"></ng-content>\n            @if (!hideClose()) {\n              <button type=\"button\" class=\"sd-side-drawer-close-btn\" (click)=\"close()\" aria-label=\"Close\">\n                <svg\n                  viewBox=\"0 0 24 24\"\n                  width=\"24\"\n                  height=\"24\"\n                  stroke=\"currentColor\"\n                  stroke-width=\"2\"\n                  fill=\"none\"\n                  stroke-linecap=\"round\"\n                  stroke-linejoin=\"round\">\n                  <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n                  <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n                </svg>\n              </button>\n            }\n          </div>\n        </div>\n        @if (_isOpened) {\n          <div class=\"sd-side-drawer-body\">\n            <div class=\"sd-side-drawer-content\">\n              <ng-content></ng-content>\n            </div>\n          </div>\n        }\n        <div class=\"sd-side-drawer-footer\">\n          <ng-content select=\"[sdFooter]\"></ng-content>\n        </div>\n      </ng-container>\n    }\n  </div>\n  @if (_isOpened) {\n    <div\n      aria-hidden=\"true\"\n      class=\"sd-side-drawer-backdrop\"\n      (click)=\"disableBackdropClose() ? null : close()\"\n      (wheel)=\"preventScroll($event)\"\n      (touchmove)=\"preventScroll($event)\"></div>\n  }\n</ng-template>\n", styles: [".sd-side-drawer{position:fixed;right:0;top:0;bottom:0;background-color:#fff;z-index:999;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translate3d(100%,0,0);transition:all .3s ease-in-out;pointer-events:none;box-shadow:0 .4px .8px #0000001a,0 3px 6px #0003}.sd-side-drawer-active{opacity:1;visibility:visible;pointer-events:all;transform:translateZ(0)}.sd-side-drawer-header{min-height:64px;padding:12px 16px;display:flex;align-items:center;justify-content:space-between}.sd-side-drawer-header-actions{display:flex;align-items:center;gap:8px}.sd-side-drawer-title{font-size:20px;line-height:28px;font-weight:500;flex:1;margin-right:16px}.sd-side-drawer-close-btn{background:transparent;border:none;padding:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--sd-secondary-color, #666);border-radius:50%;transition:background-color .2s,color .2s}.sd-side-drawer-close-btn:hover{background-color:#0000000a;color:var(--sd-primary-color, #333)}.sd-side-drawer-close-btn:focus{outline:none;background-color:#00000014}.sd-side-drawer-body{flex:1;position:relative}.sd-side-drawer-content{position:absolute;padding:0 16px 16px;inset:0;overflow:auto}.sd-side-drawer-footer{border-top:1px solid #dde0e5;padding:8px}.sd-side-drawer-backdrop{background-color:#0006;border:0;outline:none!important;position:fixed;inset:0;z-index:99;width:100%;height:100%;transition:all .3s ease-in-out}\n"] }]
        }], ctorParameters: () => [], propDecorators: { portal: [{ type: i0.ViewChild, args: [i0.forwardRef(() => CdkPortal), { isSignal: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], hideClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideClose", required: false }] }], disableBackdropClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableBackdropClose", required: false }] }], drawerClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawerClass", required: false }] }], autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], sdClosed: [{ type: i0.Output, args: ["sdClosed"] }] } });

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

export { SdSideDrawer };
//# sourceMappingURL=sdcorejs-angular-components-side-drawer.mjs.map
