import { Effect } from 'effect';
import { shouldApplyBatch } from '../../replica-state.js';
import { EngineSyncError } from '../errors.js';
export function createEngineReplicaSyncService(args) {
    return {
        connectClient(client) {
            return Effect.tryPromise({
                try: async () => {
                    const existing = args.state.getSyncClientConnection();
                    args.state.setSyncClientConnection(null);
                    if (existing) {
                        await existing.disconnect();
                    }
                    args.state.setSyncState('syncing');
                    const connection = await client.connect({
                        applyRemoteBatch: (batch) => Effect.runSync(this.applyRemoteBatch(batch)),
                        applyRemoteSnapshot: (snapshot) => {
                            args.applyRemoteSnapshot(snapshot);
                        },
                        setState: (state) => {
                            args.state.setSyncState(state);
                        },
                    });
                    args.state.setSyncClientConnection(connection);
                    if (args.state.getSyncState() === 'syncing') {
                        args.state.setSyncState('live');
                    }
                },
                catch: (cause) => new EngineSyncError({
                    message: 'Failed to connect sync client',
                    cause,
                }),
            });
        },
        disconnectClient() {
            return Effect.tryPromise({
                try: async () => {
                    const connection = args.state.getSyncClientConnection();
                    args.state.setSyncClientConnection(null);
                    if (connection) {
                        await connection.disconnect();
                    }
                    args.state.setSyncState('local-only');
                },
                catch: (cause) => new EngineSyncError({
                    message: 'Failed to disconnect sync client',
                    cause,
                }),
            });
        },
        applyRemoteBatch(batch) {
            return Effect.try({
                try: () => {
                    if (!shouldApplyBatch(args.state.replicaState, batch)) {
                        return false;
                    }
                    args.applyRemoteBatchNow(batch);
                    return true;
                },
                catch: (cause) => new EngineSyncError({
                    message: 'Failed to apply remote batch',
                    cause,
                }),
            });
        },
    };
}
//# sourceMappingURL=replica-sync-service.js.map