import { APPROVAL } from '../app/approvals/types.js';
function defaultIdFactory() {
    return `approval-${Math.random().toString(36).slice(2, 10)}`;
}
export class RemoteApprovalController {
    autoApproveSettings;
    idFactory;
    now;
    onRequested;
    onResolved;
    pending = new Map();
    listeners = new Set();
    constructor(options) {
        this.autoApproveSettings = options.autoApproveSettings;
        this.idFactory = options.idFactory ?? defaultIdFactory;
        this.now = options.now ?? (() => new Date());
        this.onRequested = options.onRequested;
        this.onResolved = options.onResolved;
    }
    isAutoApproved() {
        return this.autoApproveSettings.getAutoApprove();
    }
    onAcceptAll() {
        this.autoApproveSettings.setAutoApprove(true);
    }
    getPending() {
        return [...this.pending.values()].map((entry) => entry.approval);
    }
    subscribe(listener) {
        this.listeners.add(listener);
        return () => {
            this.listeners.delete(listener);
        };
    }
    async requestApproval(request, _ctx) {
        if (this.isAutoApproved() && !request.alwaysRequireExplicitApproval) {
            return APPROVAL.ACCEPT;
        }
        const approval = {
            id: this.idFactory(),
            request,
            createdAt: this.now().toISOString()
        };
        return new Promise((resolve) => {
            this.pending.set(approval.id, {
                approval,
                resolve
            });
            this.onRequested?.(approval);
            this.emit({ type: 'requested', approval });
        });
    }
    resolve(id, choice) {
        const entry = this.pending.get(id);
        if (!entry) {
            return false;
        }
        this.pending.delete(id);
        if (choice === APPROVAL.ACCEPT_ALL) {
            this.onAcceptAll();
        }
        entry.resolve(choice);
        this.onResolved?.(entry.approval, choice);
        this.emit({ type: 'resolved', approval: entry.approval, choice });
        return true;
    }
    rejectAll(choice = APPROVAL.REJECT) {
        const approvals = [...this.pending.values()];
        this.pending.clear();
        for (const entry of approvals) {
            entry.resolve(choice);
            this.onResolved?.(entry.approval, choice);
            this.emit({ type: 'resolved', approval: entry.approval, choice });
        }
        return approvals.map((entry) => entry.approval.id);
    }
    emit(event) {
        for (const listener of this.listeners) {
            listener(event);
        }
    }
}
//# sourceMappingURL=approval-controller.js.map