// Copyright 2026 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.
import { options } from 'preact';
import { globalCommitContext, resetGlobalCommitContext, takeRemovedSubtreesForCurrentCommit, } from './commit-context.js';
import { COMMIT } from '../../shared/render-constants.js';
import { hook } from '../../utils.js';
import { formatElementTemplateUpdateCommands } from '../debug/alog.js';
import { profileEnd, profileStart } from '../debug/profile.js';
import { globalPipelineOptions, markTiming, markTimingLegacy, setPipeline } from '../lynx/performance.js';
import { ElementTemplateLifecycleConstant } from '../protocol/lifecycle-constant.js';
let installed = false;
let hasHydrated = false;
const scheduledRemovedSubtreeCleanupTimers = new Set();
export function markElementTemplateHydrated() {
    hasHydrated = true;
}
export function isElementTemplateHydrated() {
    return hasHydrated;
}
export function resetElementTemplateCommitState() {
    hasHydrated = false;
    resetGlobalCommitContext();
}
export function scheduleElementTemplateRemovedSubtreeCleanup(removedSubtrees) {
    if (removedSubtrees.length === 0) {
        return;
    }
    const timer = setTimeout(() => {
        scheduledRemovedSubtreeCleanupTimers.delete(timer);
        for (const root of removedSubtrees) {
            root.tearDown();
        }
    }, 10000);
    scheduledRemovedSubtreeCleanupTimers.add(timer);
}
export function cancelElementTemplateRemovedSubtreeCleanup() {
    for (const timer of scheduledRemovedSubtreeCleanupTimers) {
        clearTimeout(timer);
    }
    scheduledRemovedSubtreeCleanupTimers.clear();
}
export function installElementTemplateCommitHook() {
    if (installed) {
        return;
    }
    installed = true;
    hook(options, COMMIT, (originalCommit, vnode, commitQueue) => {
        if (__BACKGROUND__ && hasHydrated && globalCommitContext.ops.length > 0) {
            markTimingLegacy('updateDiffVdomEnd');
            markTiming('diffVdomEnd');
            if (__PROFILE__) {
                profileStart('ReactLynx::commitChanges');
            }
            markTiming('packChangesStart');
            if (globalPipelineOptions) {
                globalCommitContext.flushOptions.pipelineOptions = globalPipelineOptions;
            }
            markTiming('packChangesEnd');
            if (globalPipelineOptions) {
                setPipeline(undefined);
            }
            if (__PROFILE__) {
                profileEnd();
            }
            if (typeof __ALOG__ !== 'undefined' && __ALOG__) {
                console.alog?.('[ReactLynxDebug] ElementTemplate BTS -> MTS update:\n'
                    + JSON.stringify({
                        ops: formatElementTemplateUpdateCommands(globalCommitContext.ops),
                        flushOptions: globalCommitContext.flushOptions,
                        flowIds: globalCommitContext.flowIds,
                    }, null, 2));
            }
            const removedSubtrees = takeRemovedSubtreesForCurrentCommit();
            try {
                lynx.getCoreContext().dispatchEvent({
                    type: ElementTemplateLifecycleConstant.update,
                    data: {
                        ops: globalCommitContext.ops,
                        flushOptions: globalCommitContext.flushOptions,
                        flowIds: globalCommitContext.flowIds,
                    },
                });
            }
            finally {
                resetGlobalCommitContext();
                // Match Snapshot's cleanup boundary: start the delayed teardown only
                // after the bridge dispatch attempt, so background JS objects are not
                // torn down before main-thread detach observes the same commit.
                scheduleElementTemplateRemovedSubtreeCleanup(removedSubtrees);
            }
        }
        originalCommit?.(vnode, commitQueue);
    });
}
//# sourceMappingURL=commit-hook.js.map