import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, Input, inject, signal } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
import { registerStreamingSlot } from './core/streamingSlotRegistrar.js';
import { isAngularDeferSlotPayload } from './defer-slot-payload.js';
import { DeferErrorTemplateDirective, DeferFallbackTemplateDirective, DeferResolvedTemplateDirective } from './defer-slot-templates.directive.js';
import * as i0 from "@angular/core";
export class DeferSlotComponent {
    constructor() {
        this.cdr = inject(ChangeDetectorRef);
        this.runtimeReady = signal(false, ...(ngDevMode ? [{ debugName: "runtimeReady" }] : /* istanbul ignore next */ []));
        this.id = '';
        this.slotData = signal({}, ...(ngDevMode ? [{ debugName: "slotData" }] : /* istanbul ignore next */ []));
        this.state = signal('fallback', ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
        this.activeTemplate = () => {
            if (this.state() === 'resolved') {
                return this.resolvedTemplate?.templateRef ?? null;
            }
            if (this.state() === 'error') {
                return (this.errorTemplate?.templateRef ??
                    this.fallbackTemplate?.templateRef ??
                    null);
            }
            return (this.fallbackTemplate?.templateRef ??
                this.resolvedTemplate?.templateRef ??
                null);
        };
        this.templateContext = () => {
            const slotData = this.slotData();
            return {
                $implicit: slotData,
                slotData
            };
        };
    }
    ngOnInit() {
        const id = this.id;
        if (!id)
            return;
        if (typeof window === 'undefined') {
            const payloadPromise = this.payload;
            if (!payloadPromise)
                return;
            registerStreamingSlot({
                id,
                resolve: () => payloadPromise
            });
            return;
        }
        const consumers = (window.__ABS_SLOT_CONSUMERS__ =
            window.__ABS_SLOT_CONSUMERS__ ?? {});
        consumers[id] = (payload) => {
            if (!this.runtimeReady())
                return false;
            this.applyPatchPayload(payload);
            return true;
        };
    }
    ngAfterViewInit() {
        if (typeof window === 'undefined')
            return;
        requestAnimationFrame(() => {
            this.runtimeReady.set(true);
            this.cdr.markForCheck();
            window.__ABS_SLOT_FLUSH__?.();
        });
    }
    ngOnDestroy() {
        if (typeof window === 'undefined')
            return;
        const id = this.id;
        if (!id)
            return;
        delete window.__ABS_SLOT_CONSUMERS__?.[id];
    }
    applyPatchPayload(payload) {
        if (payload == null)
            return;
        if (isAngularDeferSlotPayload(payload)) {
            const data = payload.data && typeof payload.data === 'object'
                ? payload.data
                : {};
            this.slotData.set(data);
            this.state.set(payload.state === 'error' ? 'error' : 'resolved');
            this.cdr.markForCheck();
            return;
        }
        this.slotData.set({});
        this.state.set(payload === '' ? 'fallback' : 'resolved');
        this.cdr.markForCheck();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: DeferSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: DeferSlotComponent, isStandalone: true, selector: "abs-defer-slot", inputs: { className: "className", id: "id", payload: "payload" }, queries: [{ propertyName: "resolvedTemplate", first: true, predicate: DeferResolvedTemplateDirective, descendants: true }, { propertyName: "fallbackTemplate", first: true, predicate: DeferFallbackTemplateDirective, descendants: true }, { propertyName: "errorTemplate", first: true, predicate: DeferErrorTemplateDirective, descendants: true }], ngImport: i0, template: `
		<div
			[attr.id]="'slot-' + id"
			[attr.class]="className"
			data-absolute-slot="true"
		>
			<ng-container
				[ngTemplateOutlet]="activeTemplate()"
				[ngTemplateOutletContext]="templateContext()"
			></ng-container>
		</div>
	`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: DeferSlotComponent, decorators: [{
            type: Component,
            args: [{
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    selector: 'abs-defer-slot',
                    standalone: true,
                    imports: [
                        NgTemplateOutlet,
                        DeferResolvedTemplateDirective,
                        DeferFallbackTemplateDirective,
                        DeferErrorTemplateDirective
                    ],
                    template: `
		<div
			[attr.id]="'slot-' + id"
			[attr.class]="className"
			data-absolute-slot="true"
		>
			<ng-container
				[ngTemplateOutlet]="activeTemplate()"
				[ngTemplateOutletContext]="templateContext()"
			></ng-container>
		</div>
	`
                }]
        }], propDecorators: { className: [{
                type: Input
            }], id: [{
                type: Input
            }], payload: [{
                type: Input
            }], resolvedTemplate: [{
                type: ContentChild,
                args: [DeferResolvedTemplateDirective]
            }], fallbackTemplate: [{
                type: ContentChild,
                args: [DeferFallbackTemplateDirective]
            }], errorTemplate: [{
                type: ContentChild,
                args: [DeferErrorTemplateDirective]
            }] } });
