import { ComposerTitleIndex } from './composer-title-index.js';
import { extractPageState } from './extract-page.js';
/** Avoid flashing errors when Agents panel is briefly hidden during tab switches. */
const CONTAINER_MISS_THRESHOLD = 3;
export class DOMExtractor {
    queuedMediaHints;
    timer = null;
    client = null;
    selectors;
    onState;
    containerMissStreak = 0;
    composerTitleIndex = new ComposerTitleIndex();
    /** One CDP extract at a time — overlapping polls were piling up in the CDP queue. */
    extractInFlight = false;
    constructor(selectors, onState, queuedMediaHints) {
        this.queuedMediaHints = queuedMediaHints;
        this.selectors = selectors;
        this.onState = onState;
    }
    start(client, intervalMs) {
        this.stop();
        this.client = client;
        const poll = () => void this.extract(client);
        poll();
        this.timer = setInterval(poll, intervalMs);
    }
    stop() {
        if (this.timer)
            clearInterval(this.timer);
        this.timer = null;
        this.client = null;
    }
    pollNow() {
        if (this.client)
            void this.extract(this.client);
    }
    async extract(client) {
        if (client.isCommandExclusive())
            return;
        if (this.extractInFlight)
            return;
        this.extractInFlight = true;
        try {
            const partial = await extractPageState(client, this.selectors);
            if (!partial) {
                this.containerMissStreak++;
                if (this.containerMissStreak >= CONTAINER_MISS_THRESHOLD) {
                    this.onState(null, 'Chat container not found');
                }
                return;
            }
            this.containerMissStreak = 0;
            if (!partial.pendingApprovals)
                partial.pendingApprovals = [];
            if (!partial.todos)
                partial.todos = [];
            if (!partial.queuedMessages)
                partial.queuedMessages = [];
            if (this.queuedMediaHints) {
                partial.queuedMessages = this.queuedMediaHints.syncFromDom(partial.queuedMessages);
            }
            const activeTab = partial.tabs?.find((t) => t.active);
            this.composerTitleIndex.note(activeTab?.title, partial.activeChatTitle, partial.activeComposerId);
            this.onState({
                connected: true,
                ...partial,
                composerIdByTitle: this.composerTitleIndex.snapshot(),
                pendingApprovals: partial.pendingApprovals ?? [],
                updatedAt: Date.now(),
            });
        }
        catch (err) {
            this.containerMissStreak++;
            if (this.containerMissStreak >= CONTAINER_MISS_THRESHOLD) {
                this.onState(null, err.message);
            }
        }
        finally {
            this.extractInFlight = false;
        }
    }
}
