"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "syncLastCompleted", {
    enumerable: true,
    get: function() {
        return syncLastCompleted;
    }
});
const _expressasynchandler = /*#__PURE__*/ _interop_require_default(require("express-async-handler"));
const _sequelize = require("sequelize");
const _zod = /*#__PURE__*/ _interop_require_wildcard(require("zod"));
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
const syncLastCompleted = (0, _expressasynchandler.default)(async (req, res)=>{
    req.flagPermissionChecked();
    const { store, query } = req;
    const { models: { SyncSession } } = store;
    const { page, rowsPerPage, order, orderBy } = await _zod.object({
        page: _zod.preprocess((val)=>{
            if (typeof val === 'string') {
                return Number.parseInt(val);
            }
            return val;
        }, _zod.int().min(0)).default(0),
        rowsPerPage: _zod.preprocess((val)=>{
            if (typeof val === 'string') {
                return Number.parseInt(val);
            }
            return val;
        }, _zod.int().min(1).max(50)).default(10),
        order: _zod.enum([
            'asc',
            'desc'
        ]).default('desc'),
        orderBy: _zod.enum([
            'completedAt',
            'deviceId',
            'deviceType',
            'duration',
            'facilityIds',
            'recordsPulled',
            'tick'
        ]).default('completedAt')
    }).parseAsync(query);
    const [lastCompleteds] = await store.sequelize.query(`
    SELECT
        coalesce(parameters->>'facilityIds', debug_info->>'facilityIds', debug_info->>'facilityId') AS facilities,
        max(completed_at) AS timestamp
    FROM sync_sessions
    WHERE true
        AND completed_at IS NOT NULL
        AND coalesce(parameters->>'facilityIds', debug_info->>'facilityIds', debug_info->>'facilityId') IS NOT NULL
    GROUP BY facilities
  `);
    const sessions = await Promise.all(lastCompleteds.map(async ({ facilities, timestamp })=>{
        return SyncSession.findOne({
            where: {
                completedAt: timestamp,
                [_sequelize.Op.or]: [
                    {
                        'debugInfo.facilityId': facilities
                    },
                    {
                        'debugInfo.facilityIds': facilities
                    },
                    {
                        'parameters.facilityIds': facilities
                    }
                ]
            }
        });
    }));
    res.send({
        data: sessions.map((session)=>({
                facilityIds: session.parameters.facilityIds ?? session.debugInfo.facilityIds ?? [
                    session.debugInfo.facilityId
                ],
                completedAt: session.completedAt,
                duration: session.completedAt - session.createdAt,
                deviceId: session.parameters.deviceId ?? 'unknown',
                deviceType: session.parameters.isMobile ? 'mobile' : 'facility',
                recordsPulled: session.debugInfo.totalToPull ?? 0,
                tick: session.pullSince ?? 0
            })).sort((oa, ob)=>{
            const [a, b] = order === 'desc' ? [
                ob,
                oa
            ] : [
                oa,
                ob
            ];
            if (orderBy === 'completedAt') {
                return a.completedAt - b.completedAt;
            } else if (orderBy === 'deviceId') {
                return a.deviceId?.localeCompare(b.deviceId ?? '') ?? 0;
            } else if (orderBy === 'deviceType') {
                return a.deviceType?.localeCompare(b.deviceType ?? '') ?? 0;
            } else if (orderBy === 'duration') {
                return a.duration - b.duration;
            } else if (orderBy === 'facilityIds') {
                return a.facilityIds?.[0]?.localeCompare(b.facilityIds?.[0] ?? '') ?? 0;
            } else if (orderBy === 'recordsPulled') {
                return a.recordsPulled - b.recordsPulled;
            } else if (orderBy === 'tick') {
                return a.tick - b.tick;
            } else {
                return 0;
            }
        }).slice(page * rowsPerPage, (page + 1) * rowsPerPage),
        count: lastCompleteds.length
    });
});

//# sourceMappingURL=sync.js.map