import { randomUUID } from "node:crypto";
const transactionPaidEvents = new Map();
const transactionPaidIndex = new Map();
const transactionPaidSubscribers = new Set();
function nowIso() {
    return new Date().toISOString();
}
function cloneInternalEvent(event) {
    return {
        ...event,
        payload_json: { ...event.payload_json }
    };
}
export function subscribeTransactionPaid(handler) {
    transactionPaidSubscribers.add(handler);
    return () => transactionPaidSubscribers.delete(handler);
}
export function emitTransactionPaid(payload) {
    const existingId = transactionPaidIndex.get(payload.transaction_id);
    if (existingId) {
        const events = transactionPaidEvents.get(payload.transaction_id) || [];
        const existing = events.find((event) => event.id === existingId);
        if (existing) {
            return cloneInternalEvent(existing);
        }
    }
    const event = {
        id: randomUUID(),
        event_type: "transaction.paid",
        transaction_id: payload.transaction_id,
        payload_json: payload,
        created_at: nowIso()
    };
    const bucket = transactionPaidEvents.get(payload.transaction_id) || [];
    bucket.push(event);
    transactionPaidEvents.set(payload.transaction_id, bucket);
    transactionPaidIndex.set(payload.transaction_id, event.id);
    const frozen = cloneInternalEvent(event);
    for (const listener of Array.from(transactionPaidSubscribers)) {
        listener(frozen);
    }
    return frozen;
}
export function getTransactionPaidEvents(transactionId) {
    if (transactionId) {
        return (transactionPaidEvents.get(transactionId) || []).map(cloneInternalEvent);
    }
    return Array.from(transactionPaidEvents.values()).flatMap((bucket) => bucket.map(cloneInternalEvent));
}
export function getTransactionPaidEventByTransactionId(transactionId) {
    const events = transactionPaidEvents.get(transactionId) || [];
    return events.length > 0 ? cloneInternalEvent(events[events.length - 1]) : null;
}
