"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "SyncQueuedDevice", {
    enumerable: true,
    get: function() {
        return SyncQueuedDevice;
    }
});
const _sequelize = require("sequelize");
const _datefns = require("date-fns");
const _dateTime = require("@tamanu/utils/dateTime");
const _constants = require("@tamanu/constants");
const _Model = require("./Model");
const SYNC_READY_WINDOW_MINUTES = 5;
let SyncQueuedDevice = class SyncQueuedDevice extends _Model.Model {
    static initModel(options) {
        super.init({
            // this represents the deviceId of the queued device (ie it's not randomly generated)
            id: {
                type: _sequelize.DataTypes.TEXT,
                allowNull: false,
                primaryKey: true
            },
            facilityIds: {
                type: _sequelize.DataTypes.JSONB,
                allowNull: false
            },
            lastSeenTime: {
                type: _sequelize.DataTypes.DATE
            },
            lastSyncedTick: {
                type: _sequelize.DataTypes.BIGINT
            },
            urgent: {
                type: _sequelize.DataTypes.BOOLEAN
            }
        }, {
            ...options,
            syncDirection: _constants.SYNC_DIRECTIONS.DO_NOT_SYNC,
            paranoid: false
        });
    }
    static getReadyDevicesWhereClause() {
        return {
            lastSeenTime: {
                [_sequelize.Op.gt]: (0, _dateTime.toDateTimeString)((0, _datefns.subMinutes)(new Date(), SYNC_READY_WINDOW_MINUTES))
            }
        };
    }
    static async getNextReadyDevice() {
        return await this.findOne({
            where: this.getReadyDevicesWhereClause(),
            order: [
                [
                    'urgent',
                    'DESC'
                ],
                [
                    'lastSyncedTick',
                    'ASC'
                ]
            ]
        });
    }
    static async checkSyncRequest(id, { facilityIds, urgent, lastSyncedTick }) {
        // first, update our own entry in the sync queue
        const queueRecord = await this.findByPk(id);
        if (!queueRecord) {
            // new entry in sync queue
            await this.create({
                id,
                facilityIds: JSON.stringify(facilityIds),
                lastSeenTime: (0, _dateTime.getCurrentDateTimeString)(),
                urgent,
                lastSyncedTick
            });
        } else {
            // update with most recent info
            // (always go with most urgent request - this way a user-requested urgent
            // sync won't be overwritten to non-urgent by a scheduled sync)
            await queueRecord.update({
                lastSeenTime: (0, _dateTime.getCurrentDateTimeString)(),
                urgent: urgent || queueRecord.urgent,
                lastSyncedTick
            });
        }
        // now check the queue and return the top device - if it's us, the handler will
        // start a sync (otherwise it'll get used in a "waiting behind device X" response
        return await this.getNextReadyDevice();
    }
};

//# sourceMappingURL=SyncQueuedDevice.js.map