"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FlowCache = void 0;
const mablscript_step_types_1 = require("../sharedUtils/mablscript-step-types");
class FlowCache {
    constructor(options) {
        this.options = options;
        this.cache = new Map();
        this.allFlowsLoaded = false;
        this.loadAllPromise = undefined;
    }
    async getFlow(invariantId) {
        if (this.cache.has(invariantId)) {
            return this.cache.get(invariantId);
        }
        if (this.allFlowsLoaded) {
            return undefined;
        }
        const flow = await this.fetchFlow(invariantId);
        if (flow) {
            this.cache.set(invariantId, flow);
        }
        return flow;
    }
    async getAllFlows() {
        if (!this.allFlowsLoaded) {
            await this.loadAllFlows();
        }
        return Object.fromEntries(this.cache);
    }
    async loadAllFlows() {
        if (this.allFlowsLoaded) {
            return;
        }
        if (this.loadAllPromise) {
            return this.loadAllPromise;
        }
        this.loadAllPromise = this.doLoadAllFlows();
        await this.loadAllPromise;
    }
    async doLoadAllFlows() {
        const { apiClient, workspaceId } = this.options;
        const [loginFlows, reusableFlows] = await Promise.all([
            apiClient.getFlows({ organization_id: workspaceId, flow_type: 'login' }),
            apiClient.getFlows({
                organization_id: workspaceId,
                flow_type: 'mablscript',
                reusable: true,
            }),
        ]);
        for (const flow of [...loginFlows, ...reusableFlows]) {
            if (flow.invariant_id) {
                this.cache.set(flow.invariant_id, flow);
            }
        }
        this.allFlowsLoaded = true;
    }
    async fetchFlow(invariantId) {
        const { apiClient, branchName } = this.options;
        try {
            return await apiClient.getFlow(invariantId, branchName);
        }
        catch (error) {
            console.warn(`Flow ${invariantId} not found:`, error);
            return undefined;
        }
    }
    setFlow(invariantId, flow) {
        this.cache.set(invariantId, flow);
    }
    async loadFlowsForSteps(steps) {
        const flowIds = [];
        for (const step of steps) {
            if ((0, mablscript_step_types_1.isStepWithReusableFlow)(step) && step.flowInvariantId) {
                if (!this.cache.has(step.flowInvariantId)) {
                    flowIds.push(step.flowInvariantId);
                }
            }
        }
        const uniqueIds = [...new Set(flowIds)];
        await Promise.all(uniqueIds.map((id) => this.getFlow(id)));
    }
    getCachedFlows() {
        return Object.fromEntries(this.cache);
    }
}
exports.FlowCache = FlowCache;
