import { isPlanningStateEvent, isTaskStateEvent } from "./canonical-state-events.js";
import { applyTaskStateEvent, createEmptyTaskStateProjection, replayTaskStateEvents } from "./event-applier.js";
import { applyPlanningStateEvent, createEmptyPlanningStateProjection, replayPlanningStateEvents } from "./planning-event-applier.js";
function sortBySequence(events) {
    return [...events].sort((a, b) => {
        if (a.sequence !== b.sequence) {
            return a.sequence - b.sequence;
        }
        return a.eventId.localeCompare(b.eventId);
    });
}
export function replayCanonicalStateEvents(events, options) {
    const ordered = sortBySequence(events);
    let taskProjection = createEmptyTaskStateProjection();
    let planningProjection = createEmptyPlanningStateProjection();
    let lastSequence = 0;
    for (const event of ordered) {
        lastSequence = Math.max(lastSequence, event.sequence);
        if (isTaskStateEvent(event)) {
            const applied = applyTaskStateEvent(taskProjection, event);
            if (!applied.ok) {
                return {
                    ok: false,
                    code: applied.error.code,
                    message: applied.error.message,
                    eventId: applied.error.eventId
                };
            }
            taskProjection = applied.projection;
        }
        else if (isPlanningStateEvent(event)) {
            const applied = applyPlanningStateEvent(planningProjection, event, options);
            if (!applied.ok) {
                return {
                    ok: false,
                    code: applied.error.code,
                    message: applied.error.message,
                    eventId: applied.error.eventId
                };
            }
            planningProjection = applied.projection;
        }
    }
    return {
        ok: true,
        result: {
            taskProjection,
            planningProjection,
            lastEventSequence: lastSequence
        }
    };
}
/** Convenience: replay task-only subset (existing callers). */
export function replayTaskEventsFromCanonical(events) {
    const taskEvents = events.filter(isTaskStateEvent);
    return replayTaskStateEvents(taskEvents);
}
/** Convenience: replay planning-only subset. */
export function replayPlanningEventsFromCanonical(events, options) {
    const planningEvents = events.filter(isPlanningStateEvent);
    return replayPlanningStateEvents(planningEvents, options);
}
