import { ONBOARDING_PROJECTION_GATES, ONBOARDING_PROJECTION_PUBLIC_SOURCE, ONBOARDING_PROJECTION_STATUSES, ONBOARDING_PROJECTION_TONES, readOnboardingLabel, toneForOnboardingStatus, } from "./onboardingProjectionContract.js";
const GATE_SET = new Set(ONBOARDING_PROJECTION_GATES);
const STATUS_SET = new Set(ONBOARDING_PROJECTION_STATUSES);
const TONE_SET = new Set(ONBOARDING_PROJECTION_TONES);
export class OnboardingProjectionService {
    store;
    constructor(store) {
        this.store = store;
    }
    listForWorkspace(workspaceId) {
        const items = [];
        if (workspaceId) {
            const rows = this.store.listOnboardingGates(workspaceId);
            for (const row of rows) {
                if (!GATE_SET.has(row.gate))
                    continue;
                if (!STATUS_SET.has(row.status))
                    continue;
                const label = readOnboardingLabel(row.displayLabel);
                if (!label)
                    continue;
                const status = row.status;
                // Prefer stored tone when it is one of the bounded values; otherwise
                // derive from status. The contract always emits a bounded tone.
                const tone = TONE_SET.has(row.tone)
                    ? row.tone
                    : toneForOnboardingStatus(status);
                items.push({
                    source: ONBOARDING_PROJECTION_PUBLIC_SOURCE,
                    id: row.id,
                    workspaceId: row.workspaceId,
                    gate: row.gate,
                    status,
                    tone,
                    displayLabel: label,
                    lastErrorCode: readOnboardingLabel(row.lastErrorCode ?? null),
                });
            }
        }
        return {
            contractVersion: "v1",
            generatedAt: new Date().toISOString(),
            items,
        };
    }
}
